npm package: @lumarc-db/bridge
Description: Bridge layer connecting lumarc-db core with admin dashboard
Latest version: 0.2.8

`text`: `# 🌉 @lumarc-db/bridge

> [한국어](./README.ko.md) | English

Bridge layer connecting `lumarc-db` core library with the admin dashboard and external tools.

## 📦 Installation

```bash
npm install @lumarc-db/bridge
# or
pnpm add @lumarc-db/bridge
# or
yarn add @lumarc-db/bridge
```

## 🎯 Purpose

The bridge package provides:

1. **Database Scanner**: Discover and inspect IndexedDB databases in the browser
2. **Database Communicator**: Manage connections and execute queries on `lumarc-db` instances
3. **Query Utilities**: Parse and build queries from SQL-like strings or visual configs
4. **Data Utilities**: Format, convert, and transform data between different formats

This package serves as the **communication layer** between:
- Core ORM library (`lumarc-db`)
- Admin dashboard (`@lumarc-db/admin`)
- External tools (DBeaver-like interfaces, monitoring tools, etc.)

## 🚀 Quick Start

### Basic Usage

```typescript
import { 
  dbScanner, 
  dbCommunicator,
  type IDatabaseInfo 
} from '@lumarc-db/bridge';

// 1. Discover all databases
const databases: IDatabaseInfo[] = await dbScanner.getAllDatabases();
console.log(databases);
// [
//   { name: 'myapp', version: 1, tables: [...] },
//   { name: 'cache', version: 2, tables: [...] }
// ]

// 2. Connect to a database
const schema = {
  users: {
    id: { type: 'number', primaryKey: true, autoIncrement: true },
    name: { type: 'string', required: true },
    email: { type: 'string', unique: true }
  }
};

await dbCommunicator.connect('myapp', schema, 1);

// 3. Execute queries
const result = await dbCommunicator.executeQuery('myapp', 'users',
  (table) => table.where('age').greaterThan(18).toArray()
);

console.log(result);
// {
//   success: true,
//   data: [...],
//   rowCount: 25,
//   executionTime: 12.5
// }
```

## 📚 Core Components

### 1. Database Scanner

Discover and inspect existing IndexedDB databases in the browser.

#### Get All Databases

```typescript
import { dbScanner } from '@lumarc-db/bridge';

// Get all databases with full information
const databases = await dbScanner.getAllDatabases();

console.log(databases);
// [
//   {
//     name: 'myapp',
//     version: 1,
//     tables: [
//       {
//         name: 'users',
//         keyPath: 'id',
//         autoIncrement: true,
//         recordCount: 150,
//         indexes: [
//           {
//             name: 'email',
//             keyPath: 'email',
//             unique: true,
//             multiEntry: false
//           }
//         ]
//       }
//     ]
//   }
// ]
```

#### Get Specific Database Info

```typescript
// Get detailed info about a specific database
const dbInfo = await dbScanner.getDatabaseInfo('myapp', 1);

console.log(dbInfo);
// {
//   name: 'myapp',
//   version: 1,
//   tables: [...]
// }
```

#### Check Database Existence

```typescript
// Check if a database exists
const exists = await dbScanner.databaseExists('myapp');
console.log(exists); // true or false
```

#### Get Table Record Count

```typescript
// Open connection to get record count
const request = indexedDB.open('myapp', 1);
request.onsuccess = async () => {
  const db = request.result;
  const count = await dbScanner.getTableRecordCount(db, 'users');
  console.log(`Users table has ${count} records`);
  db.close();
};
```

#### Delete Database

```typescript
// Delete a database (use with caution!)
await dbScanner.deleteDatabase('old-cache-db');
```

### 2. Database Communicator

Manage connections to `lumarc-db` instances and execute queries.

#### Connection Management

```typescript
import { dbCommunicator } from '@lumarc-db/bridge';

// Connect to database
const connected = await dbCommunicator.connect('myapp', schema, 1);

// Check connection status
const isConnected = dbCommunicator.isConnected('myapp');

// Get underlying LocalORM instance
const orm = dbCommunicator.getConnection('myapp');

// Get all connections
const connections = dbCommunicator.getAllConnections();
console.log(connections);
// [
//   {
//     dbName: 'myapp',
//     connected: true,
//     schema: {...},
//     tableNames: ['users', 'posts']
//   }
// ]

// Disconnect from database
await dbCommunicator.disconnect('myapp');

// Disconnect from all databases
await dbCommunicator.disconnectAll();
```

#### Query Execution

##### Method 1: Query Builder (Recommended)

```typescript
// Execute query using query builder
const result = await dbCommunicator.executeQuery('myapp', 'users',
  (table) => table
    .where('age').greaterThan(18)
    .and('status').equal('active')
    .orderBy('name')
    .limit(10)
    .toArray()
);

console.log(result);
// {
//   success: true,
//   data: [...],
//   rowCount: 10,
//   executionTime: 15.3
// }
```

##### Method 2: SQL-Like Strings

```typescript
// Execute SQL-like query string
const result = await dbCommunicator.executeQueryString('myapp',
  'SELECT * FROM users WHERE age > 18 AND status = \"active\" ORDER BY name LIMIT 10'
);

// Supported SQL syntax:
// - SELECT * FROM table
// - WHERE field = value
// - WHERE field > value (>, <, >=, <=, !=)
// - WHERE field IN (value1, value2)
// - WHERE field LIKE \"%pattern%\"
// - ORDER BY field [ASC|DESC]
// - LIMIT number
// - OFFSET number
```

##### Method 3: Visual Query Config (UI-Friendly)

```typescript
// Execute query from visual query builder config
const result = await dbCommunicator.executeVisualQuery('myapp', {
  table: 'users',
  filters: [
    { field: 'age', operator: '>', value: 18 },
    { field: 'status', operator: '=', value: 'active' }
  ],
  sort: { field: 'name', direction: 'ASC' },
  limit: 10,
  offset: 0
});

// This method is perfect for building no-code query interfaces
```

#### CRUD Operations

##### Insert Data

```typescript
// Add new record
const result = await dbCommunicator.insertData('myapp', 'users', {
  name: 'Alice Johnson',
  email: 'alice@example.com',
  age: 28
});

console.log(result);
// {
//   success: true,
//   data: { id: 1, name: 'Alice Johnson', email: 'alice@example.com', age: 28 },
//   rowCount: 1,
//   executionTime: 8.2
// }
```

##### Update Data

```typescript
// Update existing record
const result = await dbCommunicator.updateData('myapp', 'users', 1, {
  age: 29,
  email: 'alice.new@example.com'
});

console.log(result);
// {
//   success: true,
//   data: { id: 1, name: 'Alice Johnson', email: 'alice.new@example.com', age: 29 },
//   rowCount: 1,
//   executionTime: 6.5
// }
```

##### Delete Data

```typescript
// Delete record
const result = await dbCommunicator.deleteData('myapp', 'users', 1);

console.log(result);
// {
//   success: true,
//   data: true,
//   rowCount: 1,
//   executionTime: 5.1
// }
```

##### Get All Data

```typescript
// Get all records from table
const result = await dbCommunicator.getAllData('myapp', 'users');

console.log(result);
// {
//   success: true,
//   data: [...],
//   rowCount: 150,
//   executionTime: 18.7
// }
```

##### Get Count

```typescript
// Get record count
const result = await dbCommunicator.getCount('myapp', 'users');

console.log(result);
// {
//   success: true,
//   data: 150,
//   rowCount: 1,
//   executionTime: 3.2
// }
```

#### Transaction Execution

```typescript
// Execute transaction with automatic commit/rollback
const result = await dbCommunicator.executeTransaction('myapp',
  async (tx) => {
    // Add user
    const user = await tx.users.add({
      name: 'Bob Smith',
      email: 'bob@example.com'
    });

    // Add post for that user
    await tx.posts.add({
      userId: user.id,
      title: 'Hello World',
      content: 'My first post!'
    });

    return { user };
  },
  ['users', 'posts'] // Optional: specify tables
);

console.log(result);
// {
//   success: true,
//   data: { user: {...} },
//   rowCount: 1,
//   executionTime: 22.4
// }
```

### 3. Query Utilities

Parse and build queries from different formats.

#### Parse SQL-Like Query

```typescript
import { parseQuery } from '@lumarc-db/bridge';

// Parse SQL-like string into structured format
const parsed = parseQuery(
  'SELECT * FROM users WHERE age > 18 AND status = \"active\" ORDER BY name DESC LIMIT 10'
);

console.log(parsed);
// {
//   table: 'users',
//   where: [
//     { field: 'age', operator: '>', value: 18 },
//     { logic: 'AND', field: 'status', operator: '=', value: 'active' }
//   ],
//   orderBy: { field: 'name', direction: 'DESC' },
//   limit: 10
// }
```

#### Build Query from Parsed Config

```typescript
import { buildQueryFromParsed } from '@lumarc-db/bridge';

// Build query function from parsed config
const queryFn = buildQueryFromParsed(parsed);

// Use with any table accessor
const users = await orm.users.all();
const result = await queryFn(users);
```

#### Convert Visual Query to Parsed

```typescript
import { visualQueryToParsed } from '@lumarc-db/bridge';

// Convert visual query config to parsed format
const visualConfig = {
  table: 'users',
  filters: [
    { field: 'age', operator: '>', value: 18 },
    { field: 'status', operator: '=', value: 'active' }
  ],
  sort: { field: 'name', direction: 'DESC' },
  limit: 10
};

const parsed = visualQueryToParsed(visualConfig);
// Returns same format as parseQuery()
```

### 4. Data Utilities

Format and transform data for display and export.

#### Type Inference

```typescript
import { inferType, formatDataType } from '@lumarc-db/bridge';

// Infer data type from value
const type1 = inferType('hello');        // 'string'
const type2 = inferType(42);             // 'number'
const type3 = inferType(new Date());     // 'date'
const type4 = inferType(true);           // 'boolean'
const type5 = inferType([1, 2, 3]);      // 'array'
const type6 = inferType({ a: 1 });       // 'object'

// Format type name for display
const formatted = formatDataType('string');  // 'String'
```

#### Data Conversion

```typescript
import { convertToCSV, convertToJSON } from '@lumarc-db/bridge';

const users = [
  { id: 1, name: 'Alice', age: 25 },
  { id: 2, name: 'Bob', age: 30 }
];

// Convert to CSV
const csv = convertToCSV(users);
console.log(csv);
// id,name,age
// 1,Alice,25
// 2,Bob,30

// Convert to JSON
const json = convertToJSON(users);
console.log(json);
// [
//   { \"id\": 1, \"name\": \"Alice\", \"age\": 25 },
//   { \"id\": 2, \"name\": \"Bob\", \"age\": 30 }
// ]
```

#### Formatting Utilities

```typescript
import { 
  formatBytes, 
  formatExecutionTime, 
  formatDate 
} from '@lumarc-db/bridge';

// Format byte sizes
console.log(formatBytes(1024));           // '1.00 KB'
console.log(formatBytes(1048576));        // '1.00 MB'
console.log(formatBytes(1073741824));     // '1.00 GB'

// Format execution time
console.log(formatExecutionTime(0.5));    // '0.50 ms'
console.log(formatExecutionTime(1234));   // '1.23 s'

// Format dates
const now = new Date();
console.log(formatDate(now));             // '2024-01-15 14:30:45'
console.log(formatDate(now, 'date'));     // '2024-01-15'
console.log(formatDate(now, 'time'));     // '14:30:45'
```

#### Deep Clone

```typescript
import { deepClone } from '@lumarc-db/bridge';

const original = {
  user: { name: 'Alice', nested: { value: 42 } }
};

const cloned = deepClone(original);
cloned.user.nested.value = 100;

console.log(original.user.nested.value);  // 42 (unchanged)
console.log(cloned.user.nested.value);    // 100
```

#### Pagination

```typescript
import { paginate } from '@lumarc-db/bridge';

const allUsers = [...]; // 100 users

// Get page 2 with 10 items per page
const page = paginate(allUsers, 2, 10);

console.log(page);
// {
//   data: [...],           // 10 users
//   currentPage: 2,
//   pageSize: 10,
//   totalItems: 100,
//   totalPages: 10,
//   hasNext: true,
//   hasPrev: true
// }
```

#### Error Formatting

```typescript
import { formatError } from '@lumarc-db/bridge';

try {
  throw new Error('Database connection failed');
} catch (error) {
  const formatted = formatError(error);
  console.log(formatted);
  // {
  //   message: 'Database connection failed',
  //   code: 'UNKNOWN_ERROR',
  //   timestamp: Date
  // }
}
```

## 🎯 Use Cases

### 1. Admin Dashboard Integration

```typescript
import { dbScanner, dbCommunicator } from '@lumarc-db/bridge';

// Dashboard component
async function loadDashboard() {
  // Step 1: Discover all databases
  const databases = await dbScanner.getAllDatabases();
  
  // Step 2: Connect to selected database
  const selectedDb = databases[0];
  await dbCommunicator.connect(
    selectedDb.name,
    inferSchemaFromTables(selectedDb.tables),
    selectedDb.version
  );
  
  // Step 3: Load table data
  const result = await dbCommunicator.getAllData(selectedDb.name, 'users');
  
  return {
    databases,
    currentDb: selectedDb,
    users: result.data
  };
}
```

### 2. Query Console (DBeaver-like)

```typescript
import { dbCommunicator } from '@lumarc-db/bridge';

// SQL console component
async function executeConsoleQuery(dbName: string, sql: string) {
  const result = await dbCommunicator.executeQueryString(dbName, sql);
  
  if (result.success) {
    console.log(`✓ Query executed in ${result.executionTime}ms`);
    console.log(`  ${result.rowCount} rows returned`);
    console.table(result.data);
  } else {
    console.error(`✗ Query failed: ${result.error}`);
  }
  
  return result;
}

// Example usage
await executeConsoleQuery('myapp', 
  'SELECT * FROM users WHERE age > 25 ORDER BY name LIMIT 5'
);
```

### 3. Visual Query Builder

```typescript
import { dbCommunicator, type VisualQueryConfig } from '@lumarc-db/bridge';

// No-code query interface
async function buildAndExecuteQuery(dbName: string, config: VisualQueryConfig) {
  // User selects filters visually
  const config = {
    table: 'users',
    filters: [
      { field: 'age', operator: '>', value: 18 },
      { field: 'country', operator: '=', value: 'USA' }
    ],
    sort: { field: 'createdAt', direction: 'DESC' },
    limit: 20
  };
  
  // Execute without writing any code
  const result = await dbCommunicator.executeVisualQuery(dbName, config);
  
  return result;
}
```

### 4. Data Export Tool

```typescript
import { 
  dbCommunicator, 
  convertToCSV, 
  convertToJSON 
} from '@lumarc-db/bridge';

async function exportTableData(
  dbName: string, 
  tableName: string, 
  format: 'csv' | 'json'
) {
  // Get all data
  const result = await dbCommunicator.getAllData(dbName, tableName);
  
  if (!result.success) {
    throw new Error(`Export failed: ${result.error}`);
  }
  
  // Convert to desired format
  const exported = format === 'csv' 
    ? convertToCSV(result.data)
    : convertToJSON(result.data);
  
  // Download
  const blob = new Blob([exported], { 
    type: format === 'csv' ? 'text/csv' : 'application/json' 
  });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `${tableName}.${format}`;
  a.click();
}
```

### 5. Database Migration Helper

```typescript
import { dbScanner, dbCommunicator } from '@lumarc-db/bridge';

async function migrateDatabase(
  sourceDbName: string,
  targetDbName: string,
  schema: any
) {
  // Get source database info
  const sourceInfo = await dbScanner.getDatabaseInfo(sourceDbName, 1);
  
  // Connect to target database
  await dbCommunicator.connect(targetDbName, schema, 1);
  
  // Migrate each table
  for (const table of sourceInfo.tables) {
    const result = await dbCommunicator.getAllData(sourceDbName, table.name);
    
    if (result.success) {
      // Insert data into target
      await dbCommunicator.executeTransaction(targetDbName, async (tx) => {
        for (const row of result.data) {
          await tx[table.name].add(row);
        }
      });
      
      console.log(`✓ Migrated ${table.name}: ${result.rowCount} rows`);
    }
  }
}
```

## 📖 Type Definitions

### IDatabaseInfo

```typescript
interface IDatabaseInfo {
  name: string;
  version: number;
  tables: ITableInfo[];
}
```

### ITableInfo

```typescript
interface ITableInfo {
  name: string;
  keyPath: string | string[];
  autoIncrement: boolean;
  indexes: IIndexInfo[];
  recordCount: number;
}
```

### IIndexInfo

```typescript
interface IIndexInfo {
  name: string;
  keyPath: string | string[];
  unique: boolean;
  multiEntry: boolean;
}
```

### IQueryResult

```typescript
interface IQueryResult<T = any> {
  success: boolean;
  data?: T;
  error?: string;
  rowCount: number;
  executionTime: number;
}
```

### IConnectionInfo

```typescript
interface IConnectionInfo {
  dbName: string;
  connected: boolean;
  schema: TSchema;
  tableNames: string[];
}
```

### WhereCondition

```typescript
interface WhereCondition {
  field: string;
  operator: '=' | '>' | '<' | '>=' | '<=' | '!=' | 'IN' | 'LIKE';
  value: any;
  logic?: 'AND' | 'OR';
}
```

### ParsedQuery

```typescript
interface ParsedQuery {
  table: string;
  where?: WhereCondition[];
  orderBy?: {
    field: string;
    direction: 'ASC' | 'DESC';
  };
  limit?: number;
  offset?: number;
}
```

### VisualQueryConfig

```typescript
interface VisualQueryConfig {
  table: string;
  filters?: Array<{
    field: string;
    operator: string;
    value: any;
  }>;
  sort?: {
    field: string;
    direction: 'ASC' | 'DESC';
  };
  limit?: number;
  offset?: number;
}
```

## 🎨 Architecture

```
┌─────────────────────────────────────────────────────┐
│                  Admin Dashboard                     │
│              (@lumarc-db/admin)                      │
└────────────────────┬────────────────────────────────┘
                     │
                     │ Uses Bridge API
                     │
┌────────────────────▼────────────────────────────────┐
│                @lumarc-db/bridge                     │
│  ┌──────────────┐  ┌──────────────┐  ┌───────────┐ │
│  │   Scanner    │  │ Communicator │  │ Utilities │ │
│  │              │  │              │  │           │ │
│  │ - Discover   │  │ - Connect    │  │ - Parse   │ │
│  │ - Inspect    │  │ - Query      │  │ - Format  │ │
│  │ - Delete     │  │ - CRUD       │  │ - Convert │ │
│  └──────────────┘  └──────────────┘  └───────────┘ │
└────────────────────┬────────────────────────────────┘
                     │
                     │ Uses Core API
                     │
┌────────────────────▼────────────────────────────────┐
│                  lumarc-db (Core)                    │
│                                                       │
│  LocalORM → TableAccessor → QueryBuilder            │
│             Transaction → Schema → Storage           │
└──────────────────────┬──────────────────────────────┘
                       │
                       │ Uses Browser API
                       │
┌──────────────────────▼──────────────────────────────┐
│               IndexedDB (Browser)                    │
└─────────────────────────────────────────────────────┘
```

## 🔧 Advanced Usage

### Custom Query Parser

```typescript
import { type ParsedQuery } from '@lumarc-db/bridge';

function parseCustomQuery(query: string): ParsedQuery {
  // Your custom parsing logic
  return {
    table: 'users',
    where: [...],
    orderBy: {...},
    limit: 10
  };
}

// Use with communicator
const parsed = parseCustomQuery('YOUR CUSTOM SYNTAX');
const queryFn = buildQueryFromParsed(parsed);
```

### Connection Pool Management

```typescript
import { dbCommunicator } from '@lumarc-db/bridge';

class DatabasePool {
  private maxConnections = 5;
  
  async getConnection(dbName: string, schema: any) {
    const connections = dbCommunicator.getAllConnections();
    
    if (connections.length >= this.maxConnections) {
      // Remove oldest connection
      await dbCommunicator.disconnect(connections[0].dbName);
    }
    
    if (!dbCommunicator.isConnected(dbName)) {
      await dbCommunicator.connect(dbName, schema, 1);
    }
    
    return dbCommunicator.getConnection(dbName);
  }
}
```

### Performance Monitoring

```typescript
import { dbCommunicator } from '@lumarc-db/bridge';

class QueryMonitor {
  private queries: Array<{
    query: string;
    executionTime: number;
    timestamp: Date;
  }> = [];
  
  async executeAndMonitor(
    dbName: string,
    tableName: string,
    queryFn: any
  ) {
    const result = await dbCommunicator.executeQuery(
      dbName,
      tableName,
      queryFn
    );
    
    this.queries.push({
      query: `Query on ${tableName}`,
      executionTime: result.executionTime,
      timestamp: new Date()
    });
    
    // Alert on slow queries
    if (result.executionTime > 100) {
      console.warn('Slow query detected:', result);
    }
    
    return result;
  }
  
  getSlowQueries() {
    return this.queries.filter(q => q.executionTime > 100);
  }
  
  getAverageExecutionTime() {
    const sum = this.queries.reduce((acc, q) => acc + q.executionTime, 0);
    return sum / this.queries.length;
  }
}
```

## 🧪 Testing

```typescript
import { describe, it, expect, beforeEach } from 'vitest';
import { dbScanner, dbCommunicator } from '@lumarc-db/bridge';
import 'fake-indexeddb/auto';

describe('Bridge Layer', () => {
  const schema = {
    users: {
      id: { type: 'number', primaryKey: true, autoIncrement: true },
      name: { type: 'string', required: true }
    }
  };
  
  beforeEach(async () => {
    await dbCommunicator.connect('testdb', schema, 1);
  });
  
  it('should execute query', async () => {
    await dbCommunicator.insertData('testdb', 'users', {
      name: 'Test User'
    });
    
    const result = await dbCommunicator.getAllData('testdb', 'users');
    
    expect(result.success).toBe(true);
    expect(result.rowCount).toBe(1);
  });
  
  it('should parse SQL query', async () => {
    const result = await dbCommunicator.executeQueryString('testdb',
      'SELECT * FROM users WHERE name = \"Test User\"'
    );
    
    expect(result.success).toBe(true);
  });
});
```

## 📊 API Summary

### DatabaseScanner

| Method | Description | Returns |
|--------|-------------|---------|
| `getAllDatabases()` | Get all IndexedDB databases | `Promise<IDatabaseInfo[]>` |
| `getDatabaseInfo(name, version)` | Get database details | `Promise<IDatabaseInfo>` |
| `databaseExists(name)` | Check if database exists | `Promise<boolean>` |
| `getTableRecordCount(db, table)` | Get table row count | `Promise<number>` |
| `deleteDatabase(name)` | Delete database | `Promise<void>` |

### DatabaseCommunicator

| Method | Description | Returns |
|--------|-------------|---------|
| `connect(name, schema, version)` | Connect to database | `Promise<boolean>` |
| `disconnect(name)` | Disconnect from database | `Promise<boolean>` |
| `disconnectAll()` | Disconnect all | `Promise<void>` |
| `isConnected(name)` | Check connection status | `boolean` |
| `getConnection(name)` | Get LocalORM instance | `LocalORM` |
| `getAllConnections()` | Get all connections | `IConnectionInfo[]` |
| `executeQuery(db, table, fn)` | Execute query | `Promise<IQueryResult<T>>` |
| `executeQueryString(db, sql)` | Execute SQL-like query | `Promise<IQueryResult<any>>` |
| `executeVisualQuery(db, config)` | Execute visual query | `Promise<IQueryResult<any>>` |
| `insertData(db, table, data)` | Insert record | `Promise<IQueryResult<T>>` |
| `updateData(db, table, id, data)` | Update record | `Promise<IQueryResult<T>>` |
| `deleteData(db, table, id)` | Delete record | `Promise<IQueryResult<boolean>>` |
| `getAllData(db, table)` | Get all records | `Promise<IQueryResult<T[]>>` |
| `getCount(db, table)` | Get record count | `Promise<IQueryResult<number>>` |
| `executeTransaction(db, fn, tables)` | Execute transaction | `Promise<IQueryResult<T>>` |

### Utilities

| Function | Description | Returns |
|----------|-------------|---------|
| `inferType(value)` | Infer data type | `string` |
| `formatDataType(type)` | Format type name | `string` |
| `convertToCSV(data)` | Convert to CSV | `string` |
| `convertToJSON(data)` | Convert to JSON | `string` |
| `formatBytes(bytes)` | Format byte size | `string` |
| `formatExecutionTime(ms)` | Format time | `string` |
| `formatDate(date, format?)` | Format date | `string` |
| `deepClone(obj)` | Deep clone object | `T` |
| `paginate(data, page, size)` | Paginate array | `PaginatedResult<T>` |
| `parseQuery(sql)` | Parse SQL string | `ParsedQuery` |
| `buildQueryFromParsed(parsed)` | Build query function | `Function` |
| `visualQueryToParsed(config)` | Convert visual to parsed | `ParsedQuery` |
| `formatError(error)` | Format error | `FormattedError` |

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## 📄 License

MIT License - see LICENSE file for details.

## 🔗 Related Packages

- [lumarc-db](../core) - Core ORM library
- [@lumarc-db/admin](../admin) - Visual admin dashboard

## 📚 Further Reading

- [Core Library Documentation](../core/README.md)
- [Admin Dashboard Guide](../admin/README.md)
- [Integration Examples](./docs/integration.md)
- [API Reference](./docs/api-reference.md)