# core/coordinators/chapter.coordinator.ts

> 29 lines of code and 9 definitions.

Tree: Build tree
Language: typescript
Layer: application
Canonical: https://banes-lab.com/anatomy/build#file-build-core-coordinators-chapter-coordinator-ts
Source text: https://banes-lab.com/assets/sources/source.67e74014c617ffd97f64a990894ca5fa5bd65bc85e0394dfa8eaf900c60360fc.generated.txt

## Definitions

- `renderSurface` (lexical_declaration, line 10, exported)
- `LIST_JOIN` (lexical_declaration, line 8)
- `input` (lexical_declaration, line 14, exported)
- `render` (lexical_declaration, line 21, exported)
- `attribution` (lexical_declaration, line 22, exported)
- `unstable` (lexical_declaration, line 23, exported)
- `target` (lexical_declaration, line 27, exported)
- `chapters` (lexical_declaration, line 28, exported)
- `removed` (lexical_declaration, line 29, exported)

## Uses

- [core/loaders/chapter.loader.ts](https://banes-lab.com/source/build/core/loaders/chapter.loader.ts.md)

## Source

```typescript
import type { ChapterShape, SurfaceResult } from "#types/chapter.types";
import { NO_README_INPUTS, NO_TWINS, RENDER_UNSTABLE } from "#configuration/strings/derivation.strings";
import { attributionOf, pagesFor, rendererFor, shapeInputOf, surfaceFolder } from "#core/loaders/chapter.loader";
import { REPOSITORY_SHAPE } from "#configuration/constants/chapter.constants";
import { persistChapters } from "#core/persistence/chapter.persistence";
import { unstableChapters } from "#core/validators/chapter.validator";

const LIST_JOIN = ", ";

export const renderSurface = async function renderSurface(
    shape: ChapterShape,
    out: string | null = null,
): Promise<SurfaceResult> {
    const input = shapeInputOf(shape);
    if (input === null) {
        return { ok: false, reason: NO_TWINS + pagesFor(shape).join(LIST_JOIN) };
    }
    if (shape === REPOSITORY_SHAPE && input.readme === null) {
        return { ok: false, reason: NO_README_INPUTS };
    }
    const render = rendererFor(shape);
    const attribution = attributionOf();
    const unstable = unstableChapters(render, input, attribution);
    if (unstable.length > 0) {
        return { ok: false, reason: RENDER_UNSTABLE + unstable.join(LIST_JOIN) };
    }
    const target = out ?? surfaceFolder(shape);
    const chapters = render(input, attribution);
    const removed = await persistChapters(target, chapters);
    return { chapters, ok: true, out: target, removed };
};
```
