---
title: "quario — API reference"
description: "The quario package, covering the instance factory, the compiled report, the target contract, and the helpers a render target consumes."
url: "https://getquario.com/docs/reference/quario"
---

# quario

The engine. Compiles a definition into a tree of closures and emits an event
stream that every render target consumes.

## Creating an instance

### `quario(options?)`

```ts title="signature"
function quario(options?: QuarioOptions): Quario
```

Creates a configured instance. Host-level configuration only.

### `QuarioOptions`

| Field | Type | Meaning |
| --- | --- | --- |
| `license` | `string` | License key, verified offline once at creation. The engine marks output when the key ends before this version’s release date. |
| `locale` | `string` | Locale for `format`. Defaults to `"en-US"`. |
| `currency` | `string` | Default ISO 4217 code for `format: "currency"`. |
| `timeZone` | `string` | Timezone for `format: "date"`. Defaults to `"UTC"`. |
| `query` | `QueryOptions` | Budgets for the JSONPath selection, checked at construction. |
| `schemes` | `readonly string[]` | The URL schemes an `href` may use, lower-case and colon-terminated. Defaults to `https:` and `mailto:`. A value the engine can’t read throws a `TypeError` at construction. |

`quario()` refuses what it doesn’t understand, with a `TypeError` naming the
path, such as `options.locale`. That covers an unknown key, a value of the
wrong type, and an `options` that isn’t an object. It also covers a `locale` or
`timeZone` that `Intl` refuses, and a `currency` that isn’t three upper-case
letters. An options object shared
with other code therefore throws, so pass `quario()` only these six keys.

### `Quario`

```ts title="signature"
interface Quario {
  readonly license: Promise<LicenseInfo>
  report(schema: ReportSchema, functions?: FunctionRegistry): CompiledReport
  plan(schema: unknown, functions?: FunctionRegistry, options?: PlanOptions): Plan
}

interface PlanOptions {
  readonly targets?: readonly TargetCapabilities[]
}

interface TargetCapabilities {
  readonly target: string
  readonly declarations: Readonly<Record<string, string>>
}
```

`license` settles with the verification result and never rejects. `report`
throws on the first definition problem. `plan` returns everything one traversal
produced. An entry in `functions` that isn’t a function is a problem at
`functions.<name>`. `plan` refuses an unknown key in `options` the same way,
and a `targets` that isn’t an array throws a `TypeError`.

`options.targets` takes the `capabilities` descriptors the published targets
export beside their factories. Every declaration the document marks `required`
that one of them withdraws or leaves unread becomes a problem at
`required.<name>`. An approximated declaration isn’t one, and passing no
descriptors checks nothing.

### `LicenseInfo`

```ts title="signature"
interface LicenseInfo {
  licensed: boolean
  licensee?: string
  id?: string
}
```

## Compiling and rendering

### `CompiledReport`

```ts title="signature"
interface CompiledReport {
  stream(
    data?: unknown,
    params?: Readonly<Record<string, JsonValue>>,
  ): Generator<ReportEvent, void, undefined>
  readonly params: readonly DeclaredParam[]
  readonly names: readonly string[]
  readonly readPaths: ReadPaths
  readonly functions: readonly FunctionSignature[]
  readonly paths: readonly QueryPath[]
  render<Out>(
    target: Target<string, Out>,
    data?: unknown,
    params?: Readonly<Record<string, JsonValue>>,
  ): Promise<Awaited<Out>>
}
```

`params` supplies values for the parameters the document names. The engine
refuses a key the document doesn’t name and a value of the wrong declared
`type`. It refuses a render that leaves out a required parameter before any
expression runs.

`render` resolves the target’s output whether the target renders synchronously
or not. A malformed target throws synchronously as a definition error.

`render` also settles every [asynchronous registered
function](https://getquario.com/docs/diving-deeper/host-functions.md) the report calls, before the
target reads an event. `stream` returns events as you pull them, so it can
wait for nothing: it reports the call it reached and names the cell. A target
therefore never sees a promise, whichever way the host drives the report.

`names` is the union of free variables excluding engine anchors and group
handles. `readPaths` maps each compiled source’s schema path to the member
paths it reads off its anchors. `functions` lists the registry functions
called, in call-first-seen order. `paths` is the frozen dependency topology of
the `data` query.

```ts title="signature"
type ReadPath = readonly [string, ...(string | null)[]]
type ReadPaths = Readonly<Record<string, readonly ReadPath[]>>
```

### `DeclaredParam`

```ts title="signature"
interface DeclaredParam {
  readonly name: string
  readonly required: boolean
  readonly type?: ParamType
  readonly default?: JsonValue
  readonly label?: string
}
```

One entry per declared parameter, in declaration order. `type`, `default` and
`label` are present only where the document wrote one, and `required` is the
absence of a default. The list holds a bare value too, as an optional
parameter whose `default` is that value.

### `Target<Name, Out>`

```ts title="signature"
interface Target<Name extends string = string, Out = unknown> {
  name: Name
  compile: (stream: ReportEventStream) => (data?: unknown) => Out
}
```

The contract every render target honours. The engine calls `compile` once per
`render` call, so it must be cheap and stateless. Per-render work belongs in
the renderer it returns.

### `FunctionRegistry`

```ts title="signature"
type FunctionRegistry = Record<string, (...args: any[]) => any>
```

Host functions a definition may call. A registered name shadows a built-in of
the same name.

## Checking a definition

### `validate(schema, functions?)`

```ts title="signature"
function validate(schema: unknown, functions?: FunctionRegistry): string[]
```

Every problem in the definition, in document order, as located strings. Needs
no instance and no data.

### `Plan`

```ts title="signature"
interface Plan {
  readonly report: CompiledReport | null
  readonly params: readonly DeclaredParam[]
  readonly problems: readonly Problem[]
  readonly anchors: Readonly<Record<string, readonly string[]>>
  readonly readPaths: ReadPaths
  readonly uses: Readonly<Partial<Record<RequirableName, readonly string[]>>>
  readonly warnings: readonly Warning[]
}
```

`report` is `null` while the document has problems, and `params` is there
either way, so an editor can draw a parameter form beside the problems. `anchors` maps a compiled
source’s schema path to the anchors and handles it reads. `readPaths` maps the
same paths to the member paths each source reads, ending in `null` where it
reads on through a key the definition doesn’t name. `uses` maps each
name in `REQUIRABLE` the document writes to the paths that write it. It never adds a
problem and needs no option. `warnings` is advisory, in document order from
the same descent.

### `Problem`

```ts title="signature"
interface Problem {
  readonly path: string
  readonly source?: string
  readonly message: string
  readonly diagnostic?: QuarioDiagnostic
}
```

Frozen. `message` is exactly the string `validate` returns for this problem.

### `Warning`

```ts title="signature"
interface Warning {
  readonly path: string
  readonly message: string
}
```

An advisory says the document declares something nothing will read. Not a
`Problem` at lower severity, and not its shape. It carries no `source` and no
`diagnostic`, because nothing raised, and the engine decides nothing will read
a declaration only after every compile succeeds.

### `isDiagnostic(e)`

```ts title="signature"
function isDiagnostic(e: unknown): e is QuarioDiagnostic
```

True for a located diagnostic raised by a delegated engine, authenticated by
identity. False for quario’s own verdicts and for a registered function’s
throw.

### `QuarioDiagnostic`

```ts title="signature"
interface QuarioDiagnostic extends Error {
  readonly code?: QuarioErrorCode
  readonly start?: number
  readonly end?: number
  readonly limit?: number
  readonly actual?: number
  readonly blocks?: readonly SjabloonBlock[]
}
```

`code` is absent on option and target-definition faults. `limit` and `actual`
appear on a budget failure. Diagnostic codes sit outside the frozen authoring
surface and may change.

## Writing a target

These exports exist for code consuming the event stream. An application
rendering through `html()`, `pdf()`, `xlsx()` or `csv()` needs none of them.
[Custom targets](https://getquario.com/docs/diving-deeper/custom-target.md) covers what they’re for
and builds a complete target from them.

### `walk(events, handlers)`

```ts title="signature"
function walk(events: Iterable<ReportEvent>, handlers: WalkHandlers): Promise<void>
```

Dispatches one render’s events to per-event handlers in stream order and once
each. It pulls lazily and yields the loop between batches. Handlers are
synchronous, and a promise one returns isn’t awaited.

### `breathe()`

```ts title="signature"
function breathe(): Promise<void>
```

Yields the event loop to the host, and resolves after the host takes its turn.

### `splits(events)`

```ts title="signature"
function splits(events: Iterable<ReportEvent>): Generator<WalkEvent, void>
```

Folds each split bracket into one `split` event and passes every other event
through unchanged, lazily. Call `walk(splits(events), handlers)` where you want
a split whole rather than a bracket you track yourself.

### `collapse(events)`

```ts title="signature"
function collapse(events: Iterable<WalkEvent>): Generator<WalkEvent, void>
```

Drops the content of every instance whose group declares `collapsed`, nested
instances whole, and keeps its brackets and its own bands. Call
`walk(collapse(events), handlers)` from a target with nowhere to hide a row a
reader could open again. The engine computes aggregates before the stream, so a
footer still totals rows nobody sees.

### `text(tokens)` and `display(value)`

```ts title="signature"
function text(tokens: readonly Token[]): string
function display(value: unknown): string
```

`text` joins a token stream to display text. `display` is the scalar rule it
joins with, so a target stringifies exactly as the stream does. A valid `Date`
renders as ISO 8601 UTC, an invalid one stays `"Invalid Date"`, and nullish
displays empty.

### `typed(tokens, decl?)`

```ts title="signature"
function typed(
  tokens: readonly Token[],
  decl?: ResolvedFormat | FormatKind,
): number | boolean | Date | undefined
```

The typed-cell seam. Exactly one value token holding a finite number, a boolean
or a valid `Date` keeps its pre-stringify value. Anything else reports
`undefined`. Pass the resolved `format` to revive a date string under the
`date` kind. One run of one value token is still a single-token
array. The second argument is that token’s run’s resolved `format` rather
than the cell’s.

### `styledRuns(tokens)`

```ts title="signature"
interface TokenRun {
  style: Record<string, unknown> | null
  tokens: Token[]
}
function styledRuns(tokens: Token[]): TokenRun[]
```

Groups a cell’s tokens into its runs, in order, consecutive tokens with equal
styles forming one. `style` is `null` where the cell’s own applies. Equality
goes one level deep, which is exhaustive rather than approximate, since
`format` is the only object-valued declaration and is itself flat. The built-in
targets consume it, so a custom target grouping through it can’t drift from
them.

### `format(value, style?, options?)`

```ts title="signature"
function format(
  value: unknown,
  style?: { format?: unknown; currency?: unknown } | null,
  options?: { locale?: string; currency?: string; timeZone?: string } | null,
): string | undefined
```

Presents a token for a cell’s resolved style. Returns nothing when the kind
doesn’t apply, so the caller uses `display()` instead.

### `currencyOf(style?, options?)`

```ts title="signature"
function currencyOf(
  style?: { currency?: unknown } | null,
  options?: { currency?: string } | null,
): string | null
```

Which code a cell wears under `format: "currency"`. Branch on this rather than
on `style.currency ?? instanceCurrency`, which gets an unusable code wrong.

### `fractionDigits(style?, options?)`

```ts title="signature"
function fractionDigits(
  style?: { format?: unknown; currency?: unknown } | null,
  options?: { currency?: string } | null,
): number | undefined
```

How many fraction digits a cell presents. Returns nothing where the cell
presents no count.

### `isReportBand(role)`

```ts title="signature"
function isReportBand(role: string | undefined): boolean
```

Whether a band role names one of the report’s own bands rather than a group
instance’s.

### `hostOptions(value, keys, at)` and `hostMeta(value, at)`

```ts title="signature"
interface QuarioMeta {
  title?: string
  author?: string
  subject?: string
}

function hostOptions<T>(value: T, keys: readonly string[], at: string): T
function hostMeta<T extends QuarioMeta | null | undefined>(value: T, at: string): T
```

The checks every official target refuses its options with, exported so a target
of your own refuses them the same way. `hostOptions` closes a key set. It throws
a `TypeError` prefixed with `at` when the value carries a key outside `keys`. A
host’s typo then costs one stack trace rather than an option silently lost.
Nullish is absence, and own enumerable keys only, so an inherited property never
counts as an option the host wrote.

`hostMeta` validates the `{ title, author, subject }` contract the document
targets share — each a string, and nothing else. It checks the three once here
because every document format carries the same three. What each format calls them
inside its own package stays that target’s business. Both return the value you
give them, so a factory reads its options through them.

### `imageError(path, said, cause?)`

```ts title="signature"
function imageError(path: string | undefined, said: string, cause?: unknown): Error
```

Mints an image failure named on the item that asked for the bytes. The result
takes `cause`’s class. Not a diagnostic.

### `pageBox(page?, at?)` and `paper(page?, opening?, at?)`

```ts title="signature"
function pageBox(
  page?: PageOption,
  at?: string,
): { width: number; height: number; margin: number | PageSides }

function paper(
  page?: PageOption,
  opening?: { size?: unknown; margin?: unknown; orientation?: unknown },
  at?: string,
): {
  size: PageOption['size']
  margin: number | PageSides | undefined
  orientation: PageOption['orientation']
  width: number
  height: number
  sides: PageSides
}

interface PageOption {
  size?: 'A4' | 'letter' | [number, number]
  margin?: number | PageSides
  orientation?: 'portrait' | 'landscape'
}

interface PageSides { top: number; right: number; bottom: number; left: number }
```

The rules every target with a page follows, exported so a target of your own
applies them the same way. `pageBox` validates a host’s `page` option and
returns its box. `paper` resolves the option against the document’s opening
event. The document’s key wins, the host’s fills a gap, and both declaring one
key throws. It returns the declared keys, `undefined` where nobody declared one, plus `width`, `height` and `sides`
in points, turned by the orientation. Both throw a `TypeError` prefixed with
`at`, `"options.page"` by default.

### The vocabularies as data

```ts title="signature"
const STYLE_NAMES: readonly string[]
const RUN_STYLE_NAMES: readonly string[]
const REPORT_STYLE_NAMES: readonly string[]
const REQUIRABLE: readonly RequirableName[]
const ZERO_DASH: string
function isBoxName(name: string): boolean

const FORMAT_VOCABULARY: {
  readonly kinds: readonly FormatKind[]
  readonly forms: readonly DateForm[]
  readonly negatives: readonly NegativeReading[]
  readonly zeroes: readonly ZeroReading[]
  readonly modifiers: Readonly<Record<FormatKind, readonly string[]>>
  readonly defaultForm: DateForm
  readonly defaultNegative: NegativeReading
  readonly defaultZero: ZeroReading
  readonly maxDigits: number
}
```

The closed vocabularies as data, for a tool that offers them rather than checks
them. `RUN_STYLE_NAMES` is the inline half a styled run may wear, in the
vocabulary’s own order, and `REPORT_STYLE_NAMES` the report default’s two
names. `REQUIRABLE` is the set a document may mark `required`, and the exported
`RequirableName` is that set as a type. A marking no target could answer for is
therefore an error where an author writes it, rather than a `plan` problem
afterwards. A name outside the set is a definition error either way. `isBoxName` answers whether a style name is a padding
or a border side, the partition that defines a table row’s box. `ZERO_DASH` is
what a cell reads as under `zero: "dash"`, stated once because the XLSX target
writes the same character into its sectioned number format.

`FORMAT_VOCABULARY.modifiers` names every modifier a kind takes rather than one
of them. A surface offering them then needs no knowledge that the three number
kinds share theirs and `date` doesn’t.

```json
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://getquario.com/"},{"@type":"ListItem","position":2,"name":"Docs","item":"https://getquario.com/docs"},{"@type":"ListItem","position":3,"name":"quario","item":"https://getquario.com/docs/reference/quario"}]}
```
