# domain/loaders/surface.loader.ts

> 58 lines of code and 16 definitions.

Tree: Site tree
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/tree#file-domain-loaders-surface-loader-ts
Source text: https://banes-lab.com/source/tree/domain/loaders/surface.loader.ts.txt

Listed in [domain/loaders](https://banes-lab.com/api/source/tree/domain/loaders.md), after [domain/loaders/search.loader.ts](https://banes-lab.com/source/tree/domain/loaders/search.loader.ts.md).

## Definitions

- `isRecord` (lexical_declaration, line 8)
- `hasText` (lexical_declaration, line 12)
- `listOf` (lexical_declaration, line 16)
- `isRecording` (lexical_declaration, line 33)
- `isTextList` (lexical_declaration, line 29)
- `loadRecording` (lexical_declaration, line 55, exported)
- `isFrame` (lexical_declaration, line 25)
- `fetchRecording` (lexical_declaration, line 41)
- `isLine` (lexical_declaration, line 21)
- `recordings` (lexical_declaration, line 6)
- `held` (lexical_declaration, line 17)
- `frames` (lexical_declaration, line 37)
- `response` (lexical_declaration, line 43)
- `parsed` (lexical_declaration, line 44)
- `pending` (lexical_declaration, line 56, exported)
- `loading` (lexical_declaration, line 60, exported)

## Uses

- [core/reporters/failure.reporter.ts](https://banes-lab.com/source/tree/core/reporters/failure.reporter.ts.md)

## Used by

- [presentation/renderers/surface.renderer.ts](https://banes-lab.com/source/tree/presentation/renderers/surface.renderer.ts.md)

## Source

```typescript
import type { SurfaceFigureName, SurfaceFrame, SurfaceLine, SurfaceRecording } from "#types/surface.types";
import { SURFACE_UNAVAILABLE } from "#configuration/strings/report.strings";
import { reportFailure } from "#core/reporters/failure.reporter";
import { surfaceLocation } from "#core/assets/surface.asset";

const recordings = new Map<SurfaceFigureName, Promise<SurfaceRecording | null>>();

const isRecord = function isRecord(value: unknown): value is Record<string, unknown> {
    return typeof value === "object" && value !== null;
};

const hasText = function hasText(value: Record<string, unknown>, keys: readonly string[]): boolean {
    return keys.every((key) => typeof value[key] === "string");
};

const listOf = function listOf(value: Record<string, unknown>, key: string): readonly unknown[] {
    const held = value[key];
    return Array.isArray(held) ? held : [];
};

const isLine = function isLine(value: unknown): value is SurfaceLine {
    return isRecord(value) && hasText(value, ["text"]) && typeof value["changed"] === "boolean";
};

const isFrame = function isFrame(value: unknown): value is SurfaceFrame {
    return isRecord(value) && hasText(value, ["command", "output", "surface"]) && listOf(value, "lines").every(isLine);
};

const isTextList = function isTextList(value: Record<string, unknown>, key: string): boolean {
    return Array.isArray(value[key]) && listOf(value, key).every((entry) => typeof entry === "string");
};

const isRecording = function isRecording(value: unknown): value is SurfaceRecording {
    if (!isRecord(value) || !hasText(value, ["figure"]) || !isTextList(value, "opening")) {
        return false;
    }
    const frames = listOf(value, "frames");
    return frames.length > 0 && frames.every(isFrame);
};

const fetchRecording = async function fetchRecording(figure: SurfaceFigureName): Promise<SurfaceRecording | null> {
    try {
        const response = await fetch(surfaceLocation(figure));
        const parsed: unknown = response.ok ? await response.json() : null;
        if (isRecording(parsed)) {
            return parsed;
        }
        reportFailure(SURFACE_UNAVAILABLE, figure);
    } catch (error) {
        reportFailure(SURFACE_UNAVAILABLE, error);
    }
    return null;
};

export const loadRecording = async function loadRecording(figure: SurfaceFigureName): Promise<SurfaceRecording | null> {
    const pending = recordings.get(figure);
    if (pending !== undefined) {
        return pending;
    }
    const loading = fetchRecording(figure).then((recording) => {
        if (recording === null) {
            recordings.delete(figure);
        }
        return recording;
    });
    recordings.set(figure, loading);
    return loading;
};
```
