npm package: @hayato/core
Description: Bot core
Author: Sean Genabe
Latest version: 2.0.2

# core

Hayato's core framework

## Usage

```ts
import { App } from '@hayato/core
```

The `App` is the main class exported by this module. It refers to a base object that works with a Discord.js Client object to implement various commands.

### get/set app.name

Type: `string`
Default value: `hayato`

The name of the app. When the client is replaced, the value is emitted by the `app.observables.nameChange` observable.

Consequently, a new `app.log` with the new name will be assigned.

### get/set app.client

Type: (discord.js) `Client`
Default value: `new Client()`

The Discord.js Client instance the app is working with. A default instance is available on initialization and can be reassigned.

The client can be reassigned in order to enable scenarios that require replacing the client such as providing options to the Client constructor.

When the client is replaced, the value is emitted by the `app.observables.clientChange` observable.

Consequently, the backing instance for `app.clientEvents` will be replaced to refer to the new client. Also, the main bot logic will be routed from the new client.

### get clientEvents

A plain object whose values are observables that emit values when corresponding events are emitted by the client.

The following observables are available:

* message: `Observable<Message>`
* messageReactionAdd: `Observable<[MessageReaction, User]>`
* messageDelete: `Observable<Message>`
* ready: `Observable<void>`

See the Discord.js documentation for details.

### get router

Type: (xerpath) `OpenRadixTrie<IActionCommand, IRouteContext>`

The router for the app. The values consist of all the action commands added to the app which can be drilled to with paths using the app's own `IRouteContext`.

For documentation on the router, see [xerpath](https://www.npmjs.com/package/xerpath)

### log

Type: (pino) `Logger`

The logger for the app.

### get commands

Type: `ReadonlyArray<ITopLevelCommand | ICommand>`

.......................

### get observables

An object whose values consist of observables related to the app.

The following observables are available:

* invocationError - emits a value when the command invocation directly throws an error
* reply - emits a value when any command sends a message, either via the `send` caller or by returning a value.
* unrouted - emits a value when any message does not get routed through the app (for example when the bot prefix is not matched)
* requestHelpCommand - emits a value when a command is traversed through and requires a help command
* commandAdded - emits a value when a command is traversed through
* error - miscellaneous errors (for example when using `app.call`). Errors also cause a `log.error` line to be logged.
* routerNoMatch - emits a value when a command gets through the router but does not match any top-level command
* clientChange - emits the new client whenever the client is set
* nameChange - emits the new name whenever the name is set. A new logger with the new name will also be set.

### getPrefix

Type: `((message: Message) => MaybePromise<string>)[]`
Default value: `() => this.name + ' '`

A function that is called to determine the prefix needed for the incoming message.

Typically this would change on a per-guild basis.

### addCommand(...commands)

Adds a command to the app.

Commands persist even when the client changes.

#### commands

Type: `Command[]`

A command has the following properties:

* `title?: string` - Optional. The title of the command.
* `description?: string` - Optional. The description of the command.
* `key: ExtensiblePath<IRouteContext> | string` - Optional. The key of the command. The key is the final part of the path that will be used to access the command.
* `children?: ICommand` - Optional. Children commands to this command. The path of children is the path of this command appended by the child's key.
* `hidden?: true` - Optional. Set to `true` to hide the command from help providers.
* `usage?: string`

If the command is an action command:
* `invoke(context: ICommandContext): MaybePromise<CommandInvocationResult>`: A function to call when the command is invoked by accessing its path along with any parameters.
* `params?: Record<string, ParameterDefinition>`: Optional. An object whose keys are parameter definition names and values are parameter definitions. The following are the valid parameter definitions:
  * `{ type: 'rest' }` - a "rest" parameter
  * `{ type: 'param' }` - a single word
  * `{ type: 'optional' }` - an optional single word
  * `{ type: 'channel' }` - a Discord.js channel

### addSubscription(...subscriptions)

Adds one or more subscriptions that will be unsubscribed when the app is destroyed.

#### subscriptions

Type: (rxjs) `TeardownLogic[]`

### addAsyncTeardown(...teardownFns)

Adds one or more async functions that will be called when the app is destroyed.

#### teardownFns

Type: `(() => MaybePromise<void>)[]`

### destroy

Destroys the app by unsubscribing from subscriptions, calling async teardown functions, and calling `client.destroy`.

### call

Call a function and emit the error on the `error` observable if an error occurs.

Return type: `Promise<void>`

#### fn

Type: `() => MaybePromise<void>`