npm package: @scriptdb/dmr
Description: DMR module resolver for script database
Latest version: 1.0.0

# @scriptdb/dmr

Database Module Resolver for the script database, providing dynamic module loading and resolution capabilities for database-related modules.

## Features

- **Dynamic module loading**: Load modules from directories at runtime
- **Module registry**: Maintain a registry of all loaded modules
- **Require-like functionality**: Access modules using a require-like API
- **Import functionality**: Access modules using an import-like API
- **Context creation**: Create a context with all loaded modules

## Installation

```bash
bun add @scriptdb/dmr
```

## Quick Start

```typescript
import { DatabaseModuleResolver } from '@scriptdb/dmr';

// Resolve modules from a directory
const context = await DatabaseModuleResolver('./database-modules');

// Access modules directly from the context
const userModule = context.user;
const authModule = context.auth;

// Or use the require-like functionality
const utils = context.require('utils');
```

## API Reference

### DatabaseModuleResolver(basePath)

Resolves and loads modules from the specified directory, creating a context with all loaded modules.

```typescript
await DatabaseModuleResolver(basePath: string): Promise<Record<string, any>>
```

- `basePath` (string): The base directory path where modules are located

Returns a promise that resolves with a context object containing all loaded modules.

### Context Methods

#### require(moduleName)

Loads a module by name.

```typescript
context.require(moduleName: string): any
```

- `moduleName` (string): The name of the module to load

Returns the module's default export if available, otherwise the module itself.

#### import(moduleName)

Asynchronously loads a module by name.

```typescript
context.import(moduleName: string): Promise<{ default: any }>
```

- `moduleName` (string): The name of the module to load

Returns a promise that resolves with an object containing the module's default export.

## Module Structure

To be compatible with the Database Module Resolver, your modules should be TypeScript files (.ts) in the specified directory:

```
database-modules/
├── user.ts          # User module
├── auth.ts          # Authentication module
├── utils.ts         # Utility module
└── index.ts         # Optional main entry point
```

Each module can export functions, classes, or objects:

```typescript
// database-modules/user.ts
export interface User {
  id: number;
  name: string;
  email: string;
}

export class UserService {
  async getUser(id: number): Promise<User> {
    // Implementation here
    return { id, name: 'John Doe', email: 'john@example.com' };
  }
}

export default new UserService();
```

## Examples

### Basic Module Loading

```typescript
import { DatabaseModuleResolver } from '@scriptdb/dmr';

// Load modules from the ./database-modules directory
const context = await DatabaseModuleResolver('./database-modules');

// Access modules directly
const userModule = context.user;
if (userModule && userModule.getUser) {
  const user = await userModule.getUser(1);
  console.log(user);
}

// Use the require-like functionality
const utils = context.require('utils');
if (utils && utils.formatDate) {
  const formattedDate = utils.formatDate(new Date());
  console.log(formattedDate);
}
```

### Module with Default Export

```typescript
// database-modules/database.ts
export class Database {
  private connection: any;

  constructor() {
    // Initialize connection
  }

  async query(sql: string, params?: any[]) {
    // Execute query
    return { sql, params, results: [] };
  }

  async close() {
    // Close connection
  }
}

export default new Database();

// main.ts
import { DatabaseModuleResolver } from '@scriptdb/dmr';

const context = await DatabaseModuleResolver('./database-modules');

// Access the default export
const db = context.database;
const result = await db.query('SELECT * FROM users');
console.log(result);
```

### Using the Import Functionality

```typescript
import { DatabaseModuleResolver } from '@scriptdb/dmr';

const context = await DatabaseModuleResolver('./database-modules');

// Use the import functionality to load a module
const module = await context.import('auth');
const authService = module.default;

if (authService && authService.authenticate) {
  const result = await authService.authenticate('username', 'password');
  console.log(result);
}
```

### Advanced Usage with Type Safety

```typescript
import { DatabaseModuleResolver } from '@scriptdb/dmr';

interface ModuleContext {
  user?: {
    getUser: (id: number) => Promise<{ id: number; name: string }>;
  };
  auth?: {
    authenticate: (username: string, password: string) => Promise<boolean>;
  };
  utils?: {
    formatDate: (date: Date) => string;
  };
  require: (moduleName: string) => any;
  import: (moduleName: string) => Promise<{ default: any }>;
}

const context = await DatabaseModuleResolver('./database-modules') as ModuleContext;

if (context.user && context.auth) {
  const user = await context.user.getUser(1);
  const isAuthenticated = await context.auth.authenticate('username', 'password');
  
  console.log(`User: ${user.name}, Authenticated: ${isAuthenticated}`);
}
```

## Error Handling

The Database Module Resolver will throw an error if:

- The specified directory doesn't exist
- There are syntax errors in the module code
- A module is not found when using require() or import()

```typescript
import { DatabaseModuleResolver } from '@scriptdb/dmr';

try {
  const context = await DatabaseModuleResolver('./non-existent-directory');
} catch (error) {
  console.error('Failed to load modules:', error.message);
}

try {
  const module = context.require('non-existent-module');
} catch (error) {
  console.error('Module not found:', error.message);
}
```

## Security Considerations

- Only load modules from trusted sources
- Validate module functionality before use
- Consider implementing a sandboxed environment for untrusted modules
- Limit module access to sensitive resources

## License

MIT