# StructuredContentModel

Source: /tuil/docs/reference/packages/content/api/structured-content-model
Locale: en

class exported by @mwillbanks/tuil-content.



{/* Generated by tooling/docs/generate-reference.ts. */}

## class [#class]

Public class exported by `@mwillbanks/tuil-content`.

```ts
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 [#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 &#123; readonly test: (value: unknown, path: string) => boolean; readonly render: (value: unknown, path: string) => string; &#125;[]` | Yes      | The `#renderers` member uses the `readonly &#123; readonly test: (value: unknown, path: string) => boolean; readonly render: (value: unknown, path: string) => string; &#125;[]` contract. | —                                                          |
| `__constructor` | `any`                                                                                                                                           | Yes      | The `__constructor` member uses the `any` contract.                                                                                                                                        | —                                                          |
| `rows`          | `() => readonly TreeRow[]`                                                                                                                      | Yes      | The `rows` member uses the `() => readonly TreeRow[]` contract.                                                                                                                            | [`TreeRow`](/tuil/docs/reference/packages/content/api/tree-row) |
| `viewport`      | `(offset: number, size: number) => readonly TreeRow[]`                                                                                          | Yes      | The `viewport` member uses the `(offset: number, size: number) => readonly TreeRow[]` contract.                                                                                            | [`TreeRow`](/tuil/docs/reference/packages/content/api/tree-row) |
| `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`](/tuil/docs/reference/packages/content/api/tree-row) |
| `copy`          | `(path: string, format: "json" \| "path" \| "text") => string`                                                                                  | Yes      | The `copy` member uses the `(path: string, format: "json" \| "path" \| "text") => string` contract.                                                                                        | —                                                          |

## Parameters [#parameters]

This declaration has no public members.

## Returns [#returns]

This declaration does not return a value.

## Throws [#throws]

No thrown errors are documented for this declaration.

## Related types [#related-types]

* [`TreeRow`](/tuil/docs/reference/packages/content/api/tree-row)

## Source [#source]

[View the secondary source reference](https://github.com/mwillbanks/tuil/blob/main/packages/content/src/index.ts)

## Package [#package]

[@mwillbanks/tuil-content](/tuil/docs/reference/packages/content)
