```ts
/**
 * Performs a topological sort on the given nodes and edges.
 * Returns an ordering where for every edge [from, to], 'from' comes before 'to'.
 * Among nodes with no unmet dependencies, selects the earliest in the input order.
 * Throws an error if a cycle exists or if an edge references a node not in nodes.
 */
export function topologicalSort(nodes: readonly string[], edges: readonly (readonly [string, string])[]): string[] {
  const nodeSet = new Set(nodes);
  
  // Validate all edges reference existing nodes
  for (const [from, to] of edges) {
    if (!nodeSet.has(from)) {
      throw new Error(`Node "${from}" in edge is not in the nodes list`);
    }
    if (!nodeSet.has(to)) {
      throw new Error(`Node "${to}" in edge is not in the nodes list`);
    }
  }

  // Build adjacency list and in-degree count
  const adj: Map<string, string[]> = new Map();
  const inDegree: Map<string, number> = new Map();

  for (const node of nodes) {
    adj.set(node, []);
    inDegree.set(node, 0);
  }

  for (const [from, to] of edges) {
    adj.get(from)!.push(to);
    inDegree.set(to, (inDegree.get(to) ?? 0) + 1);
  }

  // Initialize queue with nodes having in-degree 0, maintaining input order
  const queue: string[] = [];
  for (const node of nodes) {
    if (inDegree.get(node) === 0) {
      queue.push(node);
    }
  }

  const result: string[] = [];

  while (queue.length > 0) {
    // Take the first node (maintains input order among available nodes)
    const current = queue.shift()!;
    result.push(current);

    // Process neighbors
    for (const neighbor of adj.get(current)!) {
      inDegree.set(neighbor, inDegree.get(neighbor)! - 1);
      if (inDegree.get(neighbor) === 0) {
        queue.push(neighbor);
      }
    }

    // Re-sort queue to maintain input order among available nodes
    // Since we process nodes in input order, we need to ensure the queue stays sorted
    queue.sort((a, b) => nodes.indexOf(a) - nodes.indexOf(b));
  }

  if (result.length !== nodes.length) {
    throw new Error("Cycle detected in the graph");
  }

  return result;
}
```