-f requires all the remote commands to be crammed into that one call to ssh
It's not the -f that requires that. You'll need to do this anyway.
Scripts do not emulate keyboard input; they start programs and wait for those programs to finish. It doesn't really matter what options you use for the SSH connection – if you don't specify the command upfront but instead have it open an interactive shell, then the rest of the script doesn't go to the SSH session like keyboard input would; the script just pauses there, waiting for SSH to exit, and the rest of the script always gets run locally.
So you will need to provide the entire command upfront. It can be done through multiple lines, in several different ways, but you still need to recognize it as a single "unit" that runs one command with the specified input, not as emulation of typed lines.
As your example already has the SSH remote command specified as an argument, you can in fact continue the quoted string across multiple lines:
ssh myserver "
cd somedir &&
if ./something --check; then
./something --update
fi
echo 'Done, exiting ssh'
"
echo "Back home"
Alternatively, if you do not specify an argument, then you can send commands to the remote shell's input (the shell will be running in non-interactive mode and won't show a prompt). A basic one-line example would be:
echo "cd foo && ./something" | ssh myserver
or, in Bash (not plain sh):
ssh myserver <<< "cd foo && ./something"
(This may look similar to a plain ssh myserver "cd foo.." but functions differently – in your original, the command is sent as a separate "command" field, whereas in this example that field remains empty and the command is sent as input (stdin) to the shell.
Therefore, this will only work with remote commands that themselves do not require user input – if they do, they'll end up reading the subsequent commands as their input...)
In both of the above examples, the "quoted command" can be multi-line. Another way of specifying multiple lines is a "heredoc" (which obeys the same quoting/escaping rules as double-quoted strings):
ssh myserver <<EOF
cd foo
./frob --output=\$USER.out
echo "Remote command done"
EOF
echo "ssh exited, we're back"
Finally, there are ways to run ssh in background (with a remote shell waiting for input) and incrementally provide it input, in particular Bash's coproc or generic named pipes, but in nearly all cases they only add complexity to the process.