Function is not triggering event in node-pty terminal class

I’m using node-pty & I have a socket.io server, and I’m trying to run a terminal for the client to communicate with. It mostly works, except for one issue where the onData listener doesn’t fire when writing to my terminal.

terminal.ts

import { spawn, IPty } from "node-pty"
import { Socket } from "socket.io"
import os from "os"

export class Pty {
  socket: Socket
  ptyProcess: IPty
  shell: string

  constructor(socket: Socket, id: string) {
    this.socket = socket
    this.shell = os.platform() === "win32" ? "cmd.exe" : "bash"

    this.ptyProcess = spawn(this.shell, [], {
      name: "xterm",
      cols: 100,
      cwd: `/temp`,
    })

    this.ptyProcess.onData((data) => {
      console.log("onData", data)
      this.send(data)
    })

    this.write("hello")
  }

  write(data: string) {
    console.log("writing data", data)
    this.ptyProcess.write(data)
  }

  send(data: string) {
    this.socket.emit("terminalResponse", {
      data: Buffer.from(data, "utf-8"),
    })
  }
}

sockets.ts (very simplified)

const terminals: { [id: string]: Pty } = {}

io.on("connection", async (socket) => {
  const data = socket.data as {
    userId: string
    id: string
  }

  socket.on("createTerminal", ({ id }: { id: string }) => {
    terminals[id] = new Pty(socket, id)
  })

  socket.on("terminalData", ({ id, data }: { id: number; data: string }) => {
    if (!terminals[id]) {
      console.log("terminal not found")
      return
    }

    terminals[id].write(data)
  })
})

In the constructor of terminal.ts, I run this.write("hello") and it works as expected (triggers onData and emits the terminalResponse socket event).

In the sockets.ts file, the createTerminal listener works properly. The terminalData listener calls the write function on a terminal but it doesn’t execute the onData function.

Why is the behaviour different, and what’s causing it?