# roundel/plugin

> Every export of roundel/plugin, with its signature and doc comment: validate, register, reset, theme, contributions, registered and 2 more, plus 3 types.

Source: https://roundel.interlace.tools/docs/api/plugin

<!-- Generated by scripts/api-reference.ts from the built dist/*.d.ts. Do not edit; run `npx tsx scripts/api-reference.ts`. -->

The plugin host for roundel's half of the contract (`plugin-contract` R1, R4, R6, R8).

A plugin is one plain object shared by the whole family. This file keeps the key roundel
understands — `tokens`, a theme — and **ignores every other key without complaining**,
which is what makes the same object work on any subset of the family that is installed.
A plugin written for flagstaff registers here and contributes its theme; its `spinners`
and `components` are not roundel's business and are not an error.

**Nothing here imports flagstaff, and the shape is declared rather than imported.** Types
erase, so an import would cost nothing at run time — and it would still put flagstaff in
roundel's dependency story, which is the one thing the family promises it does not do.
Four keys declared structurally is three lines, and keeps "none requires the others"
literally true instead of true-modulo-types.

**A plugin cannot smuggle an unreadable colour in.** This file collects tokens; `fly()`
contrast-checks them against the ground exactly as it checks a hand-written theme, and
throws below 4.5:1. That is deliberately not re-implemented here: one contrast gate, in
the place that already had it (roundel R5).

```ts
import { validate, register, reset, … } from 'roundel/plugin';
```

## Functions

### contributions

Every token a plugin contributed, with who won it and who it shadowed.

```ts
function contributions(): Contribution[];
```

**Returns** `Contribution[]`

### register

Register a plugin. Later wins, like ESLint flat config: the array is ordered, a caller
reads it top to bottom, and the last word on a token is the one nearest the program.

```ts
function register(plugin: unknown): void;
```

| Parameter | Type |
| :-- | :-- |
| `plugin` | `unknown` |

**Returns** `void`

### registered

The plugins registered, in registration order.

```ts
function registered(): readonly Plugin[];
```

**Returns** `readonly Plugin[]`

### reset

Forget every registered plugin. For tests, and for a program that re-themes at runtime.

```ts
function reset(): void;
```

**Returns** `void`

### theme

The theme every registered plugin adds up to, ready for `fly()`.

It is *not* flown here. A plugin contributing colour must not decide when colour is
decided — `fly()` is called once by the program, and calling it from a `register()` would
mean the last plugin imported quietly re-flew the theme.

```ts
function theme(): Theme;
```

**Returns** `Theme`

### validate

Refuse a plugin that cannot contribute a theme, at the door.

A misspelt token name is refused rather than ignored: a plugin whose `errror` key is
silently dropped looks like it worked, and the author debugs the wrong thing.

```ts
function validate(plugin: unknown): asserts plugin is Plugin;
```

| Parameter | Type |
| :-- | :-- |
| `plugin` | `unknown` |

**Returns** `asserts plugin is Plugin`

## Classes

### PluginError

A refused plugin says what is wrong and what to do about it — the family's one vocabulary.

```ts
class PluginError extends Error {
    readonly code: PluginErrorCode;
    readonly fix: string;
    constructor(code: PluginErrorCode, message: string, fix: string);
}
```

## Constants

### CONTRACT

The plugin contract version. One number for the family — the same `1` flagstaff declares,
written out rather than imported for the reason in the file comment above.

```ts
const CONTRACT = 1;
```

## Interfaces

### Contribution

Which plugin last contributed each token — the shadowing a `plugin check` prints.

```ts
interface Contribution {
    token: string;
    value: Hex;
    from: string;
    /** Plugins that contributed this token earlier and were overridden, in order. */
    shadowed: string[];
}
```

### Plugin

The keys roundel reads. Declared structurally: any object with these fields is a plugin
here, whatever else it carries.

```ts
interface Plugin {
    name: string;
    contract?: number;
    tokens?: Record<string, string>;
}
```

## Types

### PluginErrorCode

```ts
type PluginErrorCode = 'E_PLUGIN_SCHEMA' | 'E_PLUGIN_CONTRACT' | 'E_NO_CONTRIBUTION';
```
