core/loaders/walk.loader.ts
core/loaders/walk.loader.ts is a file in Bane's Lab Site. 173 lines of code and 32 definitions.
import type { AnatomyRecords, SourceEntry } from "#types/record.types";
import { CELL_COLUMNS, REF_RADIX } from "#configuration/constants/anatomy.constants";
import type { LoadedWalk, WalkCellView, WalkCellsPayload, WalkRef } from "#types/anatomy.types";
import { SOURCE_UNAVAILABLE, WALK_UNAVAILABLE } from "#configuration/strings/report.strings";
import { sourceLocation, walkLocation } from "#core/assets/walk.assets";
import { ANATOMY_INDEX } from "#core/generated/anatomy.index.generated";
import type { SourceReferences } from "#types/code.types";
import { isVector } from "#core/predicates/resource.predicate";
import { reportFailure } from "#core/reporters/failure.reporter";
const walks = new Map<string, Promise<LoadedWalk | null>>();
const sources = new Map<string, Promise<string | null>>();
const references = new Map<string, Promise<SourceReferences>>();
const records = new Map<string, Promise<AnatomyRecords | null>>();
const NO_REFERENCES: SourceReferences = { sites: [], spans: {}, strings: {}, targets: [], words: {} };
const REFERENCE_CHANNELS: readonly (keyof SourceReferences)[] = ["spans", "strings", "words"];
const REFERENCE_LISTS: readonly (keyof SourceReferences)[] = ["sites", "targets"];
const isRecord = function isRecord(value: unknown): value is Record<string, unknown> {
return typeof value === "object" && value !== null;
};
const isPayload = function isPayload(value: unknown): value is WalkCellsPayload {
return isRecord(value) && Array.isArray(value["rows"]) && Array.isArray(value["columns"]);
};
const textOf = function textOf(cell: readonly (number | string | null)[], at: number): string {
const value = cell[at];
return typeof value === "string" ? value : "";
};
const lineOf = function lineOf(cell: readonly (number | string | null)[], at: number): number | null {
const value = cell[at];
return typeof value === "number" ? value : null;
};
const cellsOf = function cellsOf(payload: WalkCellsPayload): WalkCellView[] {
const column = function column(name: string): number {
return payload.columns.indexOf(name);
};
const [state, depth, label, file, line, name, text, severity] = [
column(CELL_COLUMNS.state),
column(CELL_COLUMNS.depth),
column(CELL_COLUMNS.label),
column(CELL_COLUMNS.file),
column(CELL_COLUMNS.line),
column(CELL_COLUMNS.name),
column(CELL_COLUMNS.text),
column(CELL_COLUMNS.severity),
];
return payload.rows.map((cell, index) => ({
depth: lineOf(cell, depth) ?? 0,
file: textOf(cell, file),
label: textOf(cell, label),
line: lineOf(cell, line),
name: textOf(cell, name),
ref: index.toString(REF_RADIX),
severity: cell[severity] === null ? null : textOf(cell, severity),
state: textOf(cell, state),
text: textOf(cell, text),
}));
};
const fetchWalk = async function fetchWalk(ref: WalkRef): Promise<LoadedWalk | null> {
try {
const [vector, data] = await Promise.all([fetch(walkLocation(ref.vector)), fetch(walkLocation(ref.cells))]);
if (!isVector(vector) || !data.ok) {
reportFailure(WALK_UNAVAILABLE, ref);
return null;
}
const parsed: unknown = await data.json();
if (!isPayload(parsed)) {
reportFailure(WALK_UNAVAILABLE, parsed);
return null;
}
return { cells: cellsOf(parsed), markup: await vector.text() };
} catch (error) {
reportFailure(WALK_UNAVAILABLE, error);
return null;
}
};
export const loadWalk = async function loadWalk(ref: WalkRef): Promise<LoadedWalk | null> {
const pending = walks.get(ref.vector);
if (pending !== undefined) {
return pending;
}
const loading = fetchWalk(ref).then((walk) => {
if (walk === null) {
walks.delete(ref.vector);
}
return walk;
});
walks.set(ref.vector, loading);
return loading;
};
const fetchSource = async function fetchSource(name: string): Promise<string | null> {
try {
const response = await fetch(sourceLocation(name));
if (!response.ok) {
reportFailure(SOURCE_UNAVAILABLE, name);
return null;
}
return await response.text();
} catch (error) {
reportFailure(SOURCE_UNAVAILABLE, error);
return null;
}
};
export const sourceEntryOf = function sourceEntryOf(path: string): SourceEntry | null {
return ANATOMY_INDEX.sources[path] ?? null;
};
export const sourceNameOf = function sourceNameOf(path: string): string | null {
return sourceEntryOf(path)?.source ?? null;
};
const isReferences = function isReferences(value: unknown): value is SourceReferences {
return (
isRecord(value) &&
REFERENCE_CHANNELS.every((key) => isRecord(value[key])) &&
REFERENCE_LISTS.every((key) => Array.isArray(value[key]))
);
};
const fetchReferences = async function fetchReferences(name: string): Promise<SourceReferences> {
try {
const response = await fetch(sourceLocation(name));
const parsed: unknown = response.ok ? await response.json() : null;
if (isReferences(parsed)) {
return parsed;
}
reportFailure(SOURCE_UNAVAILABLE, name);
} catch (error) {
reportFailure(SOURCE_UNAVAILABLE, error);
}
return NO_REFERENCES;
};
export const loadReferences = async function loadReferences(name: string | undefined): Promise<SourceReferences> {
if (name === undefined) {
return NO_REFERENCES;
}
const loading = references.get(name) ?? fetchReferences(name);
references.set(name, loading);
return loading;
};
const isRecords = function isRecords(value: unknown): value is AnatomyRecords {
return isRecord(value) && isRecord(value["node"]) && isRecord(value["definitions"]);
};
const fetchRecords = async function fetchRecords(name: string): Promise<AnatomyRecords | null> {
try {
const response = await fetch(sourceLocation(name));
const parsed: unknown = response.ok ? await response.json() : null;
if (isRecords(parsed)) {
return parsed;
}
reportFailure(SOURCE_UNAVAILABLE, name);
} catch (error) {
reportFailure(SOURCE_UNAVAILABLE, error);
}
return null;
};
export const loadRecords = async function loadRecords(name: string | undefined): Promise<AnatomyRecords | null> {
if (name === undefined) {
return null;
}
const loading = records.get(name) ?? fetchRecords(name);
records.set(name, loading);
return loading;
};
export const loadSource = async function loadSource(name: string): Promise<string | null> {
const pending = sources.get(name);
if (pending !== undefined) {
return pending;
}
const loading = fetchSource(name).then((text) => {
if (text === null) {
sources.delete(name);
}
return text;
});
sources.set(name, loading);
return loading;
};