tuil
ReferencePackages@mwillbanks/tuil-contentAPI

StructuredContentModel

class exported by @mwillbanks/tuil-content.

View rawEdit

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

MemberTypeRequiredDescriptionRelated types
#valueunknownYesThe #value member uses the unknown contract.
#expandedSet<string>YesThe #expanded member uses the Set<string> contract.
#selectedSet<string>YesThe #selected member uses the Set<string> contract.
#renderersreadonly &#123; readonly test: (value: unknown, path: string) => boolean; readonly render: (value: unknown, path: string) => string; &#125;[]YesThe #renderers member uses the readonly &#123; readonly test: (value: unknown, path: string) => boolean; readonly render: (value: unknown, path: string) => string; &#125;[] contract.
__constructoranyYesThe __constructor member uses the any contract.
rows() => readonly TreeRow[]YesThe rows member uses the () => readonly TreeRow[] contract.TreeRow
viewport(offset: number, size: number) => readonly TreeRow[]YesThe viewport member uses the (offset: number, size: number) => readonly TreeRow[] contract.TreeRow
format(path: string) => stringYesThe format member uses the (path: string) => string contract.
toggle(path: string) => voidYesThe toggle member uses the (path: string) => void contract.
expandAll() => voidYesThe expandAll member uses the () => void contract.
collapseAll() => voidYesThe collapseAll member uses the () => void contract.
select(path: string, additive?: boolean) => voidYesThe select member uses the (path: string, additive?: boolean) => void contract.
selected() => readonly string[]YesThe selected member uses the () => readonly string[] contract.
search(query: string | RegExp) => readonly TreeRow[]YesThe search member uses the (query: string | RegExp) => readonly TreeRow[] contract.TreeRow
copy(path: string, format: "json" | "path" | "text") => stringYesThe 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.

Source

View the secondary source reference

Package

@mwillbanks/tuil-content

On this page