# Agent Development Guide

This document provides guidance for LLMs working on the `@tursodatabase/serverless` TypeScript driver.

## Project Overview

This is a **fetch() API-compatible serverless database driver** for Turso Cloud that implements the SQL over HTTP protocol (internally called "hrana"). It's designed for serverless and edge compute environments like Cloudflare Workers and Vercel Edge Functions.

### Key Features
- **HTTP-based SQL execution** using the v3 cursor endpoint for streaming
- **Native streaming API** with Connection/Statement pattern
- **LibSQL compatibility layer** for drop-in replacement
- **TypeScript-first** with full type safety
- **Edge-optimized** using only `fetch()` API

## Architecture

### Core Files Structure
```
src/
├── connection.ts    # Connection class and connect() function
├── statement.ts     # Statement class with get()/all()/iterate() methods
├── protocol.ts      # Low-level SQL over HTTP protocol implementation
├── compat.ts        # LibSQL API compatibility layer
├── compat/index.ts  # Compatibility layer exports
└── index.ts         # Main package exports
```

### Package Exports
- **Main API**: `@tursodatabase/serverless` - Native streaming API
- **Compatibility**: `@tursodatabase/serverless/compat` - LibSQL-compatible API

## Native API Design

### Connection/Statement Pattern
```typescript
import { connect } from "@tursodatabase/serverless";

const client = connect({ url, authToken });
const stmt = client.prepare("SELECT * FROM users WHERE id = ?", [123]);

// Three execution modes:
const row = await stmt.get();        // First row or null
const rows = await stmt.all();       // All rows as array  
for await (const row of stmt.iterate()) { ... } // Streaming iterator
```

### Key Classes

#### Connection
- **Purpose**: Database connection and session management
- **Methods**: `prepare()`, `execute()`, `batch()`, `executeRaw()`
- **Internal**: Manages baton tokens, base URL updates, cursor streaming

#### Statement  
- **Purpose**: Prepared statement execution with multiple access patterns
- **Methods**: `get()`, `all()`, `iterate()`
- **Streaming**: `iterate()` provides row-by-row streaming via AsyncGenerator

#### Protocol Layer
- **Purpose**: HTTP cursor endpoint communication
- **Key Function**: `executeCursor()` returns streaming cursor entries
- **Protocol**: Uses v3 cursor endpoint (`/v3/cursor`) with newline-delimited JSON

## LibSQL Compatibility Layer

### Purpose
Provides drop-in compatibility with the standard libSQL client API for existing applications.

### Key Differences
- **Entry Point**: `createClient()` instead of `connect()`
- **Import Path**: `@tursodatabase/serverless/compat`
- **API Surface**: Matches libSQL client interface exactly
- **Config Validation**: Only supports `url` and `authToken`, validates against unsupported options

### Supported vs Unsupported
```typescript
// ✅ Supported
const client = createClient({ url, authToken });
await client.execute(sql, args);
await client.batch(statements);

// ❌ Unsupported (throws LibsqlError)
createClient({ url, authToken, encryptionKey: "..." }); // Validation error
await client.transaction(); // Not implemented
await client.sync(); // Not supported for remote
```

## Protocol Implementation

### SQL over HTTP (v3 Cursor)
- **Endpoint**: `POST /v3/cursor`
- **Request**: JSON with baton, batch steps
- **Response**: Streaming newline-delimited JSON entries
- **Entry Types**: `step_begin`, `row`, `step_end`, `step_error`, `error`

### Session Management
- **Baton Tokens**: Maintain session continuity across requests
- **Base URL Updates**: Handle server-side redirects/load balancing
- **URL Normalization**: Convert `libsql://` to `https://` automatically

## Testing Strategy

### Integration Tests
```
integration-tests/
├── serverless.test.mjs  # Native API tests
└── compat.test.mjs      # Compatibility layer tests
```

### Test Requirements
- **Environment Variables**: `TURSO_DATABASE_URL`, `TURSO_AUTH_TOKEN`
- **Serial Execution**: All tests use `test.serial()` to avoid conflicts
- **Real Database**: Tests run against actual Turso instance

### Running Tests
```bash
npm test  # Runs all integration tests
npm run build  # TypeScript compilation
```

## Development Guidelines

### Code Organization
- **Single Responsibility**: Each file has a clear, focused purpose
- **Type Safety**: Full TypeScript coverage with proper imports
- **Error Handling**: Use proper error classes (`LibsqlError` for compat)
- **Streaming First**: Leverage AsyncGenerator for memory efficiency

### Key Patterns
- **Protocol Abstraction**: Keep protocol details in `protocol.ts`
- **Compatibility Isolation**: LibSQL compatibility in separate module
- **Row Objects**: Arrays with column name properties (non-enumerable)
- **Config Validation**: Explicit validation with helpful error messages

### Performance Considerations
- **Streaming**: Use `iterate()` for large result sets
- **Memory**: Cursor endpoint provides constant memory usage
- **Latency**: First results available immediately with streaming

## Common Tasks

### Adding New Features
1. **Protocol**: Add to `protocol.ts` if it requires HTTP changes
2. **Connection**: Add to `connection.ts` for connection-level features  
3. **Statement**: Add to `statement.ts` for statement-level features
4. **Compatibility**: Update `compat.ts` if LibSQL compatibility needed
5. **Tests**: Add integration tests for new functionality

### Debugging Issues
1. **Check Protocol**: Use `executeRaw()` to inspect cursor entries
2. **Validate Config**: Ensure URL/auth token are correct
3. **Test Streaming**: Compare `all()` vs `iterate()` behavior
4. **Review Errors**: Check for `LibsqlError` vs generic errors

### Extending Compatibility
1. **Research LibSQL**: Check `resources/libsql-client-ts` for API patterns
2. **Validate Config**: Add validation for unsupported options
3. **Map Interfaces**: Convert between LibSQL and native formats
4. **Test Coverage**: Ensure compatibility tests cover new features

## Important Notes

### Security
- **No Secret Logging**: Never log auth tokens or sensitive data
- **Validation**: Always validate inputs, especially in compatibility layer
- **Error Messages**: Don't expose internal implementation details

### Compatibility
- **Breaking Changes**: Avoid breaking the native API
- **LibSQL Parity**: Match LibSQL behavior exactly in compatibility layer
- **Version Support**: Document which libSQL features are supported

### Edge Cases
- **Large Results**: Test with large datasets to verify streaming
- **Network Issues**: Handle connection failures gracefully
- **Protocol Evolution**: Be prepared for protocol version updates

## Future Considerations

### Potential Enhancements
- **Transaction Support**: Interactive transactions in compatibility layer
- **Prepared Statement Caching**: Cache prepared statements
- **Connection Pooling**: Multiple concurrent connections
- **Protocol Negotiation**: Support multiple protocol versions

### Monitoring
- **Performance Metrics**: Track query latency and throughput
- **Error Rates**: Monitor protocol and application errors
- **Resource Usage**: Memory and CPU usage in serverless environments

This guide should help future contributors understand the architecture and maintain consistency across the codebase.