Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 60 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@

JavaScript/TypeScript client SDK for the [Fila](https://github.com/faisca/fila) message broker.

Uses the Fila binary protocol (FIBP) over TCP for all communication.

## Installation

```bash
npm install @fila/client
npm install fila-client
```

## Usage

```typescript
import { Client } from "@fila/client";
import { Client } from "fila-client";

const client = new Client("localhost:5555");
await client.connect();

// Enqueue a message.
const msgId = await client.enqueue(
Expand All @@ -35,17 +38,16 @@ for await (const msg of client.consume("my-queue")) {
}
}

client.close();
await client.close();
```

### TLS (system trust store)

If the Fila server uses a certificate signed by a public CA, enable TLS without providing a CA certificate the OS system trust store is used automatically:
If the Fila server uses a certificate signed by a public CA, enable TLS without providing a CA certificate -- the OS system trust store is used automatically:

```typescript
import { Client } from "@fila/client";

const client = new Client("localhost:5555", { tls: true });
await client.connect();
```

### TLS (custom CA certificate)
Expand All @@ -54,65 +56,59 @@ For self-signed or private CA certificates, pass the CA cert explicitly:

```typescript
import * as fs from "fs";
import { Client } from "@fila/client";
import { Client } from "fila-client";

const client = new Client("localhost:5555", {
caCert: fs.readFileSync("ca.pem"),
});
await client.connect();
```

### Mutual TLS (mTLS)

Client certificates work with both modes system trust store or custom CA:
Client certificates work with both modes -- system trust store or custom CA:

```typescript
import * as fs from "fs";
import { Client } from "@fila/client";
import { Client } from "fila-client";

// With custom CA:
const client = new Client("localhost:5555", {
caCert: fs.readFileSync("ca.pem"),
clientCert: fs.readFileSync("client.pem"),
clientKey: fs.readFileSync("client.key"),
});

// With system trust store:
const client2 = new Client("localhost:5555", {
tls: true,
clientCert: fs.readFileSync("client.pem"),
clientKey: fs.readFileSync("client.key"),
});
await client.connect();
```

### API key authentication

```typescript
import { Client } from "@fila/client";

const client = new Client("localhost:5555", {
apiKey: "my-api-key",
});
await client.connect();
```

### mTLS + API key

```typescript
import * as fs from "fs";
import { Client } from "@fila/client";
import { Client } from "fila-client";

const client = new Client("localhost:5555", {
caCert: fs.readFileSync("ca.pem"),
clientCert: fs.readFileSync("client.pem"),
clientKey: fs.readFileSync("client.key"),
apiKey: "my-api-key",
});
await client.connect();
```

## API

### `new Client(addr: string, options?: ClientOptions)`

Connect to a Fila broker at the given address (e.g., `"localhost:5555"`).
Create a client for the given address (e.g., `"localhost:5555"`). Call `connect()` to establish the connection.

**Options:**

Expand All @@ -122,34 +118,70 @@ Connect to a Fila broker at the given address (e.g., `"localhost:5555"`).
| `caCert` | `Buffer` | CA certificate PEM. Enables TLS with a custom CA when set. |
| `clientCert`| `Buffer` | Client certificate PEM for mTLS. Requires TLS to be enabled. |
| `clientKey` | `Buffer` | Client private key PEM for mTLS. Requires TLS to be enabled. |
| `apiKey` | `string` | API key sent as `Bearer` token on every RPC call. |
| `apiKey` | `string` | API key sent in the FIBP handshake. |
| `batchMode` | `string` | Enqueue batching: `'auto'` (default), `'linger'`, or `'disabled'`. |

### `client.connect(): Promise<void>`

Establish the TCP connection (with optional TLS) and perform the FIBP handshake.

### `client.enqueue(queue, headers, payload): Promise<string>`

Enqueue a message. Returns the broker-assigned message ID (UUIDv7).

### `client.enqueueMany(messages): Promise<EnqueueResult[]>`

Enqueue multiple messages in a single batch request. Returns per-message results.

### `client.consume(queue): AsyncIterable<ConsumeMessage>`

Open a streaming consumer. Returns an async iterable that yields messages as they become available. Nacked messages are redelivered on the same stream.
Open a streaming consumer. Returns an async iterable that yields messages as they become available.

### `client.ack(queue, msgId): Promise<void>`

Acknowledge a successfully processed message. The message is permanently removed.
Acknowledge a successfully processed message.

### `client.nack(queue, msgId, error): Promise<void>`

Negatively acknowledge a failed message. The message is requeued or routed to the dead-letter queue based on the queue's configuration.
Negatively acknowledge a failed message.

### `client.close(): Promise<void>`

Close the client, draining any pending batched messages first.

### Admin operations

- `client.createQueue(name, opts?): Promise<string>` -- Create a queue.
- `client.deleteQueue(queue): Promise<void>` -- Delete a queue.
- `client.getStats(queue): Promise<QueueStats>` -- Get queue statistics.
- `client.listQueues(): Promise<{ clusterNodeCount, queues }>` -- List all queues.
- `client.setConfig(key, value): Promise<void>` -- Set a runtime config key.
- `client.getConfig(key): Promise<string>` -- Get a runtime config value.
- `client.listConfig(prefix): Promise<Array<{ key, value }>>` -- List config entries.
- `client.redrive(dlqQueue, count): Promise<bigint>` -- Redrive DLQ messages.

### `client.close(): void`
### Auth operations

Close the underlying gRPC channel.
- `client.createApiKey(name, opts?): Promise<{ keyId, key, isSuperadmin }>` -- Create an API key.
- `client.revokeApiKey(keyId): Promise<void>` -- Revoke an API key.
- `client.listApiKeys(): Promise<ApiKeyInfo[]>` -- List all API keys.
- `client.setAcl(keyId, permissions): Promise<void>` -- Set ACL permissions.
- `client.getAcl(keyId): Promise<{ keyId, isSuperadmin, permissions }>` -- Get ACL permissions.

## Error Handling

Per-operation error classes are thrown for specific failure modes:

```typescript
import { QueueNotFoundError, MessageNotFoundError } from "@fila/client";
import {
QueueNotFoundError,
MessageNotFoundError,
UnauthorizedError,
ForbiddenError,
NotLeaderError,
QueueAlreadyExistsError,
ProtocolError,
} from "fila-client";

try {
await client.enqueue("missing-queue", null, Buffer.from("test"));
Expand Down
50 changes: 0 additions & 50 deletions generated/admin.ts

This file was deleted.

12 changes: 0 additions & 12 deletions generated/fila/v1/AckRequest.ts

This file was deleted.

8 changes: 0 additions & 8 deletions generated/fila/v1/AckResponse.ts

This file was deleted.

12 changes: 0 additions & 12 deletions generated/fila/v1/AclPermission.ts

This file was deleted.

19 changes: 0 additions & 19 deletions generated/fila/v1/ApiKeyInfo.ts

This file was deleted.

12 changes: 0 additions & 12 deletions generated/fila/v1/ConfigEntry.ts

This file was deleted.

10 changes: 0 additions & 10 deletions generated/fila/v1/ConsumeRequest.ts

This file was deleted.

11 changes: 0 additions & 11 deletions generated/fila/v1/ConsumeResponse.ts

This file was deleted.

15 changes: 0 additions & 15 deletions generated/fila/v1/CreateApiKeyRequest.ts

This file was deleted.

14 changes: 0 additions & 14 deletions generated/fila/v1/CreateApiKeyResponse.ts

This file was deleted.

13 changes: 0 additions & 13 deletions generated/fila/v1/CreateQueueRequest.ts

This file was deleted.

10 changes: 0 additions & 10 deletions generated/fila/v1/CreateQueueResponse.ts

This file was deleted.

Loading
Loading