# Channels API for Bun and Node

Every public class, function and type of the Channels engine in `@tinyshed/tinystore`, generated from its source. The [Channels guide](https://tinyshed.org/tinystore/docs/guides/channels) explains how to use them, and the [Python](https://tinyshed.org/tinystore/docs/reference/python/channels), [Go](https://tinyshed.org/tinystore/docs/reference/go/channels) and [Rust](https://tinyshed.org/tinystore/docs/reference/rust/channels) pages list the same API.

## Message

```ts
interface Message<T> {
    value: T
    branch: string[]
}
```

A message as a subscriber receives it: what was published, and the branch it was published under.

## Missed

```ts
interface Missed {
    reason: 'behind' | 'reconnect'
    count?: number | undefined
}
```

Messages a subscriber may have lost: it fell behind its branch's log, and
`count` says how many; or its connection was lost and made again, and how
many is unknown.

## SubscribeOptions

```ts
interface SubscribeOptions {
    /** take every branch below this one too */
    recursive?: boolean | undefined
    /** told what was missed, in line with the messages; the store's log says it when absent */
    onMissed?: ((missed: Missed) => unknown) | undefined
    /** told what the handler threw, with the message; the store's log says it when absent */
    onError?: ((error: unknown, message: Message<unknown>) => unknown) | undefined
}
```

## EachOptions

```ts
interface EachOptions {
    recursive?: boolean | undefined
    onMissed?: ((missed: Missed) => unknown) | undefined
}
```

## Channel

```ts
class Channel<T> {
    readonly name: string
    readonly branch: readonly string[]
}
```

A channel of messages of one type, or one of its branches: open it with `store.channel(name)`.

### Channel.under

```ts
under(...owners: Key[]): Channel<T>
```

The branch of owners under this one: whose messages these are.

### Channel.publish

```ts
publish(value: T): Promise<void>
```

Hands value to every subscriber of this branch, and of the branches above
it listened to recursive, that listens now. It answers once the store
has the message, not once anyone handled it.

### Channel.subscribe

```ts
subscribe(handler: (message: Message<T>) => unknown, options?: SubscribeOptions): Promise<Subscription>
```

Calls handler with each message published from now on, one at a time
and in order: it answers once the store has the subscription, so that a
message published after it arrives.

```
const sub = await chat.under(roomId).subscribe(m => show(m.value), { onMissed: () => reload() })
await sub.stop()
```

### Channel.each

```ts
each(options?: EachOptions): AsyncGenerator<Message<T>>
```

The messages published from now on, as a loop: it listens from its first
turn, and break ends it. A throw in the loop's body ends it too.

```
for await (const m of chat.under(roomId).each()) await save(m.value)
```

## Subscription

```ts
class Subscription {}
```

A subscription whose handler is called with each message: `stop` ends
it, and the store's close does.

### Subscription.stop

```ts
stop(): Promise<void>
```

No call starts after it, and it answers once the running call ended;
called from inside the subscription's own handler, it answers at once.

### Subscription.start

```ts
start(handler: (message: Message<unknown>) => unknown, options: SubscribeOptions | undefined): Promise<void>
```

Registers the subscription, then runs its handler in the background.

## TxChannel

```ts
interface TxChannel<T> {
    under(...owners: Key[]): TxChannel<T>
    publish(value: T): Promise<void>
}
```

A channel inside a transaction: its messages are handed over once the transaction commits.
