The query graph: nodes, the connections between them, and the selected node, which is both the node highlighted in the editor and the node whose output is executed (the capture node).

Immutable: every operation returns a new query. Each operation has a canX predicate that is total and side-effect free, for the UI to enable menu items and drop targets; the operation itself throws when its predicate fails.

Constructors

  • Asserts the invariants, throwing on any violation:

    1. node ids are unique;
    2. every connection's source and target are nodes of the query;
    3. a node's output feeds at most one node, so the graph is a forest of trees;
    4. selected is undefined or the id of a node;
    5. selected is undefined if and only if there are no nodes;
    6. there is no cycle;
    7. every connection targets a port its target node has.

    Port capacity (one connection per target port) is not an invariant: the operations enforce it.

    Parameters

    • nodes: readonly QueryNode[] = []
    • connections: readonly Connection[] = []
    • Optionalselected: string

    Returns Query

Methods

  • Adds the node. With afterId, splices it into the chain after that node: afterId feeds the new node's first port, and whatever afterId fed is now fed by the new node. The new node is selected if nothing was, or if it goes after the selected node.

    Parameters

    Returns Query

  • Whether the node can be added: its id is new, and when it goes after another node, that node exists and the new node has an input port and accepts new inputs.

    Parameters

    Returns boolean

  • Whether sourceId can feed targetId, on port if given, else on the target's first free port: both exist and differ, the source feeds nothing yet, the port is free, the target accepts new inputs, and the target is not upstream of the source, which would close a cycle.

    Parameters

    • sourceId: string
    • targetId: string
    • Optionalport: string

    Returns boolean

  • Whether the node can be moved after another: both exist and differ, the node has an input port and accepts new inputs, and it isn't already fed by afterId. Moving can't create a cycle, since the node is disconnected first.

    Parameters

    • nodeId: string
    • afterId: string

    Returns boolean

  • Whether the node can replace the node of the query with the same id: it is a new node object (a different key) and has every port the existing connections into it use.

    Parameters

    Returns boolean

  • Whether the node is a binary node with at least one input, which accepts new inputs

    Parameters

    • nodeId: string

    Returns boolean

  • A new query object with the same content, e.g. for undo, whose change detection needs a new identity

    Returns Query

  • Connects sourceId to targetId, on port if given, else on the target's first free port

    Parameters

    • sourceId: string
    • targetId: string
    • Optionalport: string

    Returns Query

  • A new id for a node of the type: the type followed by one more than the highest number used by nodes of that type, starting at 101, e.g. filter101, filter102. If that id is taken (by a node of another type), the lowest free number from 1 is used instead.

    Parameters

    • type: string

    Returns string

  • The node's input ports that nothing feeds yet, in port order

    Parameters

    • nodeId: string

    Returns string[]

  • The ids of the nodes feeding each input port of the node, in port order; undefined for an empty port

    Parameters

    • nodeId: string

    Returns (undefined | string)[]

  • Whether the output of upstreamId reaches nodeId, directly or through other nodes

    Parameters

    • upstreamId: string
    • nodeId: string

    Returns boolean

  • Moves the node after another: disconnects it, healing the chain it leaves, then splices it in after afterId as add() does. Selection follows add() too: moving a node after the selected node selects it.

    Parameters

    • nodeId: string
    • afterId: string

    Returns Query

  • Removes the node and heals the chain: when it had an input and an output, its first input in port order now feeds its output's target. If it was selected, the selection moves to the node that fed it, else to the node it fed, else to the last node left.

    Parameters

    • nodeId: string

    Returns Query

  • Swaps the two inputs of a binary node, e.g. to turn a left outer join around. The node's settings follow its inputs (withSwappedInputs).

    Parameters

    • nodeId: string

    Returns Query

  • Whether the query is valid, given the validity found for each node by schema inference: not empty, and every node has an empty list of errors.

    Parameters

    • validity: ReadonlyMap<string, readonly string[]>

    Returns boolean