# Azion KV library

import DocButton from '~/components/webkit/DocButton.vue';

The **KV** library provides a Redis-like interface to interact with Azion's **KV Store**. This library offers familiar Redis patterns including event-based error handling, connection management, and hash operations.

<DocButton href="/en/documentation/products/azion-lib/overview/" label="Go to Azion Libraries Overview" kind="secondary" size="medium" />

You can interact with the API using a `client` with Redis-like chaining patterns. The client supports both native runtime and API-based providers with automatic detection.

This is an example of how a `.env` file with your environment variables may look like:

```sh
AZION_TOKEN=<your-api-token>
AZION_DEBUG=true
```

| Variable | Description |
|----------|-------------|
| `AZION_TOKEN` | Your Azion API token. |
| `AZION_DEBUG` | Enable debug mode (true/false). |

---

## Usage

### Creating a client

Create a KV client using the Redis-like chaining pattern:

```typescript
import { createClient } from 'azion/kv';
import type { KVClient } from 'azion/kv';

// Create a client with Redis-like chaining pattern
const client: KVClient = await createClient()
  .on('error', (err) => console.log('KV Client Error', err))
  .connect();
```

You can also create a client with custom options:

```typescript
import { createClient } from 'azion/kv';

const client = await createClient({
  namespace: 'my-namespace',
  apiToken: 'my-token',
})
  .on('error', (err) => console.error('KV Error:', err))
  .connect();
```

**Parameters**:

| Parameter | Type | Description |
|-----------|------|-------------|
| `options` | `KVClientOptions` (optional) | Configuration options for the client. |
| `options.namespace` | `string` (optional) | The namespace to use for KV operations. |
| `options.apiToken` | `string` (optional) | The API token for authentication. |

**Returns**:

| Return Type | Description |
|-------------|-------------|
| `KVClient` | A client object with methods to interact with KV Store. |

---

### `get`

Retrieves a value by key.

```typescript
const value = await client.get('my-key');
console.log(value);
```

**Parameters**:

| Parameter | Type | Description |
|-----------|------|-------------|
| `key` | `string` | The key to retrieve. |
| `options` | `KVGetOptions` (optional) | Options for the get operation. |

**Returns**:

| Return Type | Description |
|-------------|-------------|
| `Promise<KVGetValue \| null>` | The value or null if not found. |

---

### `getWithMetadata`

Retrieves a value along with its metadata.

```typescript
const result = await client.getWithMetadata('my-key');
console.log(result.value, result.metadata);
```

**Parameters**:

| Parameter | Type | Description |
|-----------|------|-------------|
| `key` | `string` | The key to retrieve. |
| `options` | `KVGetOptions` (optional) | Options for the get operation. |

**Returns**:

| Return Type | Description |
|-------------|-------------|
| `Promise<KVGetResult>` | An object containing the value and metadata. |

---

### `set`

Stores a value with an optional expiration and metadata.

```typescript
// Simple set
await client.set('my-key', 'my-value');

// Set with options
await client.set('my-key', 'my-value', {
  expiration: {
    type: 'EX',
    value: 10, // 10 seconds
  },
  metadata: { userId: '123' },
});
```

**Parameters**:

| Parameter | Type | Description |
|-----------|------|-------------|
| `key` | `string` | The key to store. |
| `value` | `KVValue` | The value to store. |
| `options` | `KVSetOptions` (optional) | Options for the set operation. |

The `KVSetOptions` object supports the following properties:

| Option | Type | Description |
|--------|------|-------------|
| `expiration` | `object` (optional) | Expiration configuration. |
| `expiration.type` | `'EX' \| 'PX' \| 'EXAT' \| 'PXAT'` | Expiration type. |
| `expiration.value` | `number` | Expiration value. |
| `metadata` | `object` (optional) | Metadata to associate with the key. |

**Expiration types**:

| Type | Description |
|------|-------------|
| `EX` | Expire in seconds from now. |
| `PX` | Expire in milliseconds from now. |
| `EXAT` | Expire at a specific Unix timestamp (seconds). |
| `PXAT` | Expire at a specific Unix timestamp (milliseconds). |

**Returns**:

| Return Type | Description |
|-------------|-------------|
| `Promise<void>` | Resolves when the operation is complete. |

---

### `delete` / `del`

Deletes a key from the store.

```typescript
await client.delete('my-key');
// or
await client.del('my-key');
```

**Parameters**:

| Parameter | Type | Description |
|-----------|------|-------------|
| `key` | `string` | The key to delete. |

**Returns**:

| Return Type | Description |
|-------------|-------------|
| `Promise<void>` | Resolves when the operation is complete. |

---

### Hash operations

The KV library supports Redis-like hash operations for storing field-value pairs.

#### `hSet` / `HSET`

Sets a field in a hash.

```typescript
await client.hSet('my-key', 'field', 'value');
await client.HSET('my-key', 'field', 'value');
```

**Parameters**:

| Parameter | Type | Description |
|-----------|------|-------------|
| `key` | `string` | The hash key. |
| `field` | `string` | The field name. |
| `value` | `KVValue` | The value to store. |

**Returns**:

| Return Type | Description |
|-------------|-------------|
| `Promise<void>` | Resolves when the operation is complete. |

#### `hGetAll` / `HGETALL`

Gets all fields and values from a hash.

```typescript
const result = await client.hGetAll('my-key');
const result = await client.HGETALL('my-key');
```

**Parameters**:

| Parameter | Type | Description |
|-----------|------|-------------|
| `key` | `string` | The hash key. |

**Returns**:

| Return Type | Description |
|-------------|-------------|
| `Promise<KVGetValue \| null>` | The hash data or null if not found. |

#### `hVals` / `HVALS`

Gets all values from a hash.

```typescript
const result = await client.hVals('my-key');
const result = await client.HVALS('my-key');
```

**Parameters**:

| Parameter | Type | Description |
|-----------|------|-------------|
| `key` | `string` | The hash key. |

**Returns**:

| Return Type | Description |
|-------------|-------------|
| `Promise<KVGetValue[] \| null>` | An array of values or null if not found. |

---

### Connection management

#### `disconnect` / `quit`

Disconnects from the KV store.

```typescript
await client.disconnect();
// or
await client.quit();
```

**Returns**:

| Return Type | Description |
|-------------|-------------|
| `Promise<void>` | Resolves when disconnected. |

---

### Provider detection

#### `getProviderType`

Returns the current provider type being used.

```typescript
const providerType = client.getProviderType();
console.log(providerType); // 'native' or 'api'
```

**Returns**:

| Return Type | Description |
|-------------|-------------|
| `'native' \| 'api'` | The provider type. |

The client automatically detects the environment:
- **native**: Used when running in Azion Runtime (Functions).
- **api**: Used when running outside of Azion Runtime (local development, external servers).

---

## Error handling

The KV client uses an event-based error handling pattern similar to Redis:

```typescript
const client = await createClient()
  .on('error', (err) => {
    console.error('KV Client Error:', err);
    // Handle error appropriately
  })
  .connect();
```

You can also use try-catch for individual operations:

```typescript
try {
  const value = await client.get('my-key');
} catch (error) {
  console.error('Failed to get value:', error);
}
```

---

## Complete example

```typescript
import { createClient } from 'azion/kv';

async function main() {
  // Create and connect client
  const client = await createClient({
    namespace: 'my-namespace',
  })
    .on('error', (err) => console.error('KV Error:', err))
    .connect();

  // Store a value with expiration
  await client.set('user:123', JSON.stringify({ name: 'John', role: 'admin' }), {
    expiration: { type: 'EX', value: 3600 }, // 1 hour
    metadata: { createdBy: 'system' },
  });

  // Retrieve the value
  const userData = await client.get('user:123');
  console.log('User data:', userData);

  // Get with metadata
  const result = await client.getWithMetadata('user:123');
  console.log('Value:', result.value);
  console.log('Metadata:', result.metadata);

  // Hash operations
  await client.hSet('config', 'theme', 'dark');
  await client.hSet('config', 'language', 'en');
  const config = await client.hGetAll('config');
  console.log('Config:', config);

  // Check provider type
  console.log('Provider:', client.getProviderType());

  // Delete and disconnect
  await client.delete('user:123');
  await client.disconnect();
}

main();
```

---

## Types

These are the types used by the **KV** library:

### `KVClient`

The main client interface for KV operations.

| Method | Parameters | Return Type | Description |
|--------|------------|-------------|-------------|
| `on` | `event: 'error', handler: (error: Error) => void` | `this` | Register error event handler (chainable). |
| `connect` | - | `Promise<this>` | Connect to KV store (chainable). |
| `get` | `key: string, options?: KVGetOptions` | `Promise<KVGetValue \| null>` | Get a value. |
| `getWithMetadata` | `key: string, options?: KVGetOptions` | `Promise<KVGetResult>` | Get value with metadata. |
| `set` | `key: string, value: KVValue, options?: KVSetOptions` | `Promise<void>` | Set a value. |
| `delete` | `key: string` | `Promise<void>` | Delete a key. |
| `del` | `key: string` | `Promise<void>` | Alias for delete. |
| `disconnect` | - | `Promise<void>` | Disconnect from store. |
| `quit` | - | `Promise<void>` | Alias for disconnect. |
| `hSet` | `key: string, field: string, value: KVValue` | `Promise<void>` | Set hash field. |
| `HSET` | `key: string, field: string, value: KVValue` | `Promise<void>` | Alias for hSet. |
| `hGetAll` | `key: string` | `Promise<KVGetValue \| null>` | Get all hash fields. |
| `HGETALL` | `key: string` | `Promise<KVGetValue \| null>` | Alias for hGetAll. |
| `hVals` | `key: string` | `Promise<KVGetValue[] \| null>` | Get all hash values. |
| `HVALS` | `key: string` | `Promise<KVGetValue[] \| null>` | Alias for hVals. |
| `getProviderType` | - | `'native' \| 'api'` | Get current provider type. |

### `KVClientOptions`

Configuration options for the KV client.

| Property | Type | Description |
|----------|------|-------------|
| `namespace` | `string` (optional) | The namespace for KV operations. |
| `apiToken` | `string` (optional) | The API token for authentication. |

### `KVSetOptions`

Options for set operations.

| Property | Type | Description |
|----------|------|-------------|
| `expiration` | `{ type: 'EX' \| 'PX' \| 'EXAT' \| 'PXAT', value: number }` (optional) | Expiration configuration. |
| `metadata` | `object` (optional) | Metadata to associate with the key. |

### `KVGetResult`

Result from getWithMetadata operation.

| Property | Type | Description |
|----------|------|-------------|
| `value` | `KVGetValue \| null` | The retrieved value. |
| `metadata` | `object \| null` | The associated metadata. |