StructuredContentModel
class exported by @mwillbanks/tuil-content.
class
Public class exported by @mwillbanks/tuil-content.
export class StructuredContentModel {
readonly #value: unknown;
readonly #expanded = new Set<string>();
readonly #selected = new Set<string>();
readonly #renderers: readonly {
readonly test: (value: unknown, path: string) => boolean;
readonly render: (value: unknown, path: string) => string;
}[];
constructor(
value: unknown,
expandRoot = true,
renderers: readonly {
readonly test: (value: unknown, path: string) => boolean;
readonly render: (value: unknown, path: string) => string;
}[] = [],
) {
this.#value = value;
this.#renderers = Object.freeze([...renderers]);
if (expandRoot) this.#expanded.add("$");
}
rows(): readonly TreeRow[] {
return Object.freeze(flattenValue(this.#value, this.#expanded));
}
viewport(offset: number, size: number): readonly TreeRow[] {
const start = Math.max(0, Math.floor(offset));
return Object.freeze(
this.rows().slice(start, start + Math.max(0, Math.floor(size))),
);
}
format(path: string): string {
const value = resolveJsonPath(this.#value, path);
const renderer = this.#renderers.find((item) => item.test(value, path));
if (renderer) return renderer.render(value, path);
if (typeof value === "string") return value;
return cycleSafeStringify(value);
}
toggle(path: string): void {
if (this.#expanded.has(path)) this.#expanded.delete(path);
else this.#expanded.add(path);
}
expandAll(): void {
const seen = new WeakSet<object>();
const visit = (value: unknown, path: string) => {
if (value === null || typeof value !== "object") return;
if (seen.has(value)) return;
seen.add(value);
this.#expanded.add(path);
for (const [key, child] of Object.entries(
value as Record<string, unknown>,
)) {
visit(child, childPath(path, key, Array.isArray(value)));
}
};
visit(this.#value, "$");
}
collapseAll(): void {
this.#expanded.clear();
}
select(path: string, additive = false): void {
if (!additive) this.#selected.clear();
this.#selected.add(path);
}
selected(): readonly string[] {
return Object.freeze([...this.#selected]);
}
search(query: string | RegExp): readonly TreeRow[] {
const expression = typeof query === "string" ? query.toLowerCase() : query;
this.expandAll();
return Object.freeze(
this.rows().filter((row) => {
const text = `${row.path} ${String(row.value ?? "")}`;
return typeof expression === "string"
? text.toLowerCase().includes(expression)
: testExpression(expression, text);
}),
);
}
copy(path: string, format: "json" | "path" | "text"): string {
if (format === "path") return path;
const value = resolveJsonPath(this.#value, path);
return format === "json" ? cycleSafeStringify(value, 2) : String(value);
}
}Members
| Member | Type | Required | Description | Related types |
|---|---|---|---|---|
#value | unknown | Yes | The #value member uses the unknown contract. | — |
#expanded | Set<string> | Yes | The #expanded member uses the Set<string> contract. | — |
#selected | Set<string> | Yes | The #selected member uses the Set<string> contract. | — |
#renderers | readonly { readonly test: (value: unknown, path: string) => boolean; readonly render: (value: unknown, path: string) => string; }[] | Yes | The #renderers member uses the readonly { readonly test: (value: unknown, path: string) => boolean; readonly render: (value: unknown, path: string) => string; }[] contract. | — |
__constructor | any | Yes | The __constructor member uses the any contract. | — |
rows | () => readonly TreeRow[] | Yes | The rows member uses the () => readonly TreeRow[] contract. | TreeRow |
viewport | (offset: number, size: number) => readonly TreeRow[] | Yes | The viewport member uses the (offset: number, size: number) => readonly TreeRow[] contract. | TreeRow |
format | (path: string) => string | Yes | The format member uses the (path: string) => string contract. | — |
toggle | (path: string) => void | Yes | The toggle member uses the (path: string) => void contract. | — |
expandAll | () => void | Yes | The expandAll member uses the () => void contract. | — |
collapseAll | () => void | Yes | The collapseAll member uses the () => void contract. | — |
select | (path: string, additive?: boolean) => void | Yes | The select member uses the (path: string, additive?: boolean) => void contract. | — |
selected | () => readonly string[] | Yes | The selected member uses the () => readonly string[] contract. | — |
search | (query: string | RegExp) => readonly TreeRow[] | Yes | The search member uses the (query: string | RegExp) => readonly TreeRow[] contract. | TreeRow |
copy | (path: string, format: "json" | "path" | "text") => string | Yes | The copy member uses the (path: string, format: "json" | "path" | "text") => string contract. | — |
Parameters
This declaration has no public members.
Returns
This declaration does not return a value.
Throws
No thrown errors are documented for this declaration.
Related types
Source
View the secondary source reference