# API Quick Reference

Concise reference for Acequia's public APIs.

## acequia (main module)

```javascript
import acequia from '/acequia.js'
```

### Initialization

| Method | Returns | Description |
|--------|---------|-------------|
| `acequiaReady()` | `Promise<{ deviceId, userId, publicJWK }>` | Wait for system initialization |

### Identity

| Method | Returns | Description |
|--------|---------|-------------|
| `getDeviceId()` | `string` | Persistent device identifier |
| `getUserId()` | `string` | Persistent user identifier |
| `getInstanceId()` | `string` | Per-session tab identifier |
| `getKeys()` | `{ publicKey, privateKey }` | Device crypto key pair |
| `getUserKeys()` | `{ publicKey, privateKey }` | User crypto key pair |

### Service Worker Communication

| Method | Returns | Description |
|--------|---------|-------------|
| `postToSW(message)` | `void` | Send message to service worker |
| `diagnoseRoutes()` | `Promise<SWState>` | Get SW introspection snapshot |

### Sub-modules

| Property | Type | Description |
|----------|------|-------------|
| `groups` | `{ Group }` | Group class for peer communication |
| `webrtc` | `object` | WebRTC peer management |
| `auth` | `object` | Device registration |
| `tokens` | `object` | JWT token management |
| `utils` | `object` | Utilities (createId, names, localforage, etc.) |
| `config` | `object` | Runtime configuration |

---

## Group

```javascript
const group = new acequia.groups.Group(groupId, config)
```

### Constructor Config

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `displayName` | `string` | — | **Required.** Display name in peer lists |
| `discoveryURL` | `string` | `''` | WebSocket server URL (empty = same origin) |
| `capabilities` | `string[]` | `[]` | Advertised capabilities |
| `onPeersList` | `function` | — | Callback when peer list updates |
| `onOpen` | `function` | — | WebSocket connected |
| `onClose` | `function` | — | WebSocket disconnected |
| `onError` | `function` | — | Error occurred |

### Properties

| Property | Type | Description |
|----------|------|-------------|
| `ready` | `Promise` | Resolves when connected and welcomed |
| `groupId` | `string` | Group identifier |
| `peersList` | `object` | Current peers `{ instanceId: info }` |
| `displayName` | `string` | This peer's display name |
| `router` | `Router` | Local route handler registry |

### Methods

| Method | Returns | Description |
|--------|---------|-------------|
| `registerRoute(pattern, handler, metadata?)` | `void` | Register single route (sends WS message) |
| `registerRoutes(routes)` | `void` | Batch register (single WS message) |
| `connectToPeer(instanceId)` | `Promise<peer>` | Establish WebRTC connection |
| `sendRequestViaPeer(peer, request)` | `Promise<response>` | Send request via WebRTC (30s timeout) |
| `destroy()` | `void` | Leave group, close WebSocket |

### registerRoutes Format

```javascript
group.registerRoutes([
    {
        pattern: '/path/:param',
        handler: async (request) => ({ status: 200, body: '...' }),
        metadata: {},  // optional
    },
])
```

### Events (via Evented)

```javascript
group.on('welcome', (event) => {})    // Connected, routes re-registered
group.on('peersList', (peers) => {})  // Peer list updated
group.on('open', (event) => {})       // WebSocket opened
group.on('close', (event) => {})      // WebSocket closed
group.on('error', (event, err) => {}) // Error occurred
```

---

## Router

```javascript
import { Router, matchPattern } from 'acequia/routes.js'
```

### Pattern Syntax

| Syntax | Example | Matches |
|--------|---------|---------|
| Literal | `/status` | Exact path |
| `:param` | `/users/:id` | Single segment → `{ id: '123' }` |
| `*param` | `/files/*path` | Rest of path → `{ path: 'a/b/c' }` |

### matchPattern(pattern, path)

Returns `{ params, remaining }` or `null`.

### Router Methods

| Method | Returns | Description |
|--------|---------|-------------|
| `registerRoute(pattern, handler, metadata?, options?)` | `void` | Register route locally |
| `matchRoute(path)` | `{ handler, pattern, metadata, pathParams, remainingPath }` | Find matching route |
| `getRouteRegistry()` | `object` | All registered routes |

---

## WebRTC

```javascript
acequia.webrtc
```

### Methods

| Method | Returns | Description |
|--------|---------|-------------|
| `getPeers()` | `{ peerId: peer }` | All active peer connections |
| `addPeer(options, maxTries?, pausePerTry?)` | `peer` | Create peer connection |
| `onNewPeer(callback)` | `void` | Listen for new peer connections |

### Peer Object

| Property/Method | Type | Description |
|-----------------|------|-------------|
| `peerId` | `string` | Remote peer's instance ID |
| `ready` | `Promise` | Resolves when data channel open |
| `sendBig(data)` | `void` | Send large data (auto-chunked at 16KB) |
| `on('dataBig', fn)` | `void` | Receive reassembled large data |
| `on('close', fn)` | `void` | Peer disconnected |
| `on('error', fn)` | `void` | Connection error |
| `destroy()` | `void` | Close connection |

---

## Auth

```javascript
acequia.auth
```

| Method | Returns | Description |
|--------|---------|-------------|
| `register(authURL)` | `Promise` | Register device with auth server |
| `registerUser(authURL, options)` | `Promise` | Register user with device key |
| `getDeviceInfo(id, authURL)` | `Promise<info>` | Fetch device public key |
| `getPublicKey(id, authURL)` | `Promise<JWK>` | Get device's public key |

---

## Tokens

```javascript
acequia.tokens
```

| Method | Returns | Description |
|--------|---------|-------------|
| `createToken(payload, expiresTime)` | `Promise<JWT>` | Create device-signed JWT |
| `createUserToken(payload, expiresTime)` | `Promise<JWT>` | Create user-signed JWT |
| `createInvite(groupId, type, redirect, expires)` | `Promise<tokenId>` | Create invitation token |
| `verifyToken(jwt)` | `Promise<{ payload, protectedHeader }>` | Verify user token |
| `verifyDeviceToken(jwt)` | `Promise<{ payload, protectedHeader }>` | Verify device token |

---

## Utilities

```javascript
acequia.utils
```

| Property/Method | Type | Description |
|-----------------|------|-------------|
| `createId()` | `string` | Generate CUID2 identifier |
| `generateRandomName()` | `string` | "Blue Elephant" style name |
| `generateRandomSlug()` | `string` | "blue-elephant" style slug |
| `localforage` | `object` | IndexedDB storage wrapper |
| `Evented` | `class` | Event emitter base class |
| `debounced(fn, delay)` | `function` | Debounce/throttle utility |
| `isBrowser()` | `boolean` | Runtime detection |
| `isServiceWorker()` | `boolean` | Runtime detection |
| `isNode()` | `boolean` | Runtime detection |

---

## Error Classes

```javascript
import { HttpError, NotFoundError, ... } from 'acequia/errors.js'
```

| Class | Status | Code |
|-------|--------|------|
| `BadRequestError` | 400 | `BAD_REQUEST` |
| `UnauthorizedError` | 401 | `UNAUTHORIZED` |
| `ForbiddenError` | 403 | `FORBIDDEN` |
| `NotFoundError` | 404 | `NOT_FOUND` |
| `RouteNotFoundError` | 404 | `ROUTE_NOT_FOUND` |
| `MethodNotAllowedError` | 405 | `METHOD_NOT_ALLOWED` |
| `ConflictError` | 409 | `CONFLICT` |
| `RouteConflictError` | 409 | `ROUTE_CONFLICT` |
| `InternalServerError` | 500 | `INTERNAL_SERVER_ERROR` |
| `ServiceUnavailableError` | 503 | `SERVICE_UNAVAILABLE` |
| `GatewayTimeoutError` | 504 | `GATEWAY_TIMEOUT` |

### createErrorResponse(error)

Converts any error to `{ statusCode, body: { error, message, statusCode, code, timestamp } }`.