)]}'
{
  "commit": "2f927566d2d7c167383bf36fff61211f23d9e7e4",
  "tree": "c84d88a3c0537167293d2e77e2ed5ffa8f73b0f8",
  "parents": [
    "3009d88594bf1575a5a3414995f65134edf219ff"
  ],
  "author": {
    "name": "Jason Bedard",
    "email": "jason+github@jbedard.ca",
    "time": "Fri Jul 17 12:30:09 2026 -0700"
  },
  "committer": {
    "name": "GitHub",
    "email": "noreply@github.com",
    "time": "Fri Jul 17 12:30:09 2026 -0700"
  },
  "message": "fix(watch): read the socket with a single persistent reader (#2925)\n\nThe previous per-receive \u0027data\u0027 listener had two framing bugs that\ncaused occasional crashes or hangs of watch protocol clients such as\njs_run_devserver:\n\n- multiple messages coalesced into one chunk were parsed as a single\nJSON document, rejecting with a SyntaxError\n- messages arriving while no receive was pending were silently dropped,\ndeadlocking the client and server\n\nA single persistent reader now splits the stream on newlines, buffers\npartial lines across chunks, and queues messages until consumed. Socket\nerrors and close reject the pending and all future receives instead of\nleaking unhandled \u0027error\u0027 events.\n\nFix #2894\n\n### Changes are visible to end-users: no\n\n### Test plan\n\n- Covered by existing test cases\n- New test cases added",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "4072a543125379e1ef8793f9c278a570c2142640",
      "old_mode": 33188,
      "old_path": "js/private/devserver/js_run_devserver.mjs",
      "new_id": "038538b4ab87682504e737f29bbe42a92f5835f8",
      "new_mode": 33188,
      "new_path": "js/private/devserver/js_run_devserver.mjs"
    },
    {
      "type": "modify",
      "old_id": "55a66637ff172ef38f3fe5b19e35a4a1a9f91613",
      "old_mode": 33188,
      "old_path": "js/private/test/watch/BUILD.bazel",
      "new_id": "b7250fc2234bbe6f165ba99777ea7f6952cd626c",
      "new_mode": 33188,
      "new_path": "js/private/test/watch/BUILD.bazel"
    },
    {
      "type": "add",
      "old_id": "0000000000000000000000000000000000000000",
      "old_mode": 0,
      "old_path": "/dev/null",
      "new_id": "0116c98b54866f1fc7c5fb68ca8f751183bf096e",
      "new_mode": 33188,
      "new_path": "js/private/test/watch/aspect_watch_protocol.test.mjs"
    },
    {
      "type": "modify",
      "old_id": "f38618ed180a5f09fffb991ba423318fd6f5d2db",
      "old_mode": 33188,
      "old_path": "js/private/watch/aspect_watch_protocol.d.mts",
      "new_id": "4d382b6abac369b6b6cb670ee80c364d192e3a6f",
      "new_mode": 33188,
      "new_path": "js/private/watch/aspect_watch_protocol.d.mts"
    },
    {
      "type": "modify",
      "old_id": "de3ca4cbed8f30516cbd5472398b65df5a73afde",
      "old_mode": 33188,
      "old_path": "js/private/watch/aspect_watch_protocol.mjs",
      "new_id": "ffee8fb81e27e5a42b7b1d485e846622f6de8d22",
      "new_mode": 33188,
      "new_path": "js/private/watch/aspect_watch_protocol.mjs"
    },
    {
      "type": "modify",
      "old_id": "a8468f04423e289e77232ef155650323366f3d56",
      "old_mode": 33188,
      "old_path": "js/private/watch/src/aspect_watch_protocol.mts",
      "new_id": "c20b4bcc68c4ac082248f223f5b7a24b3c1f4876",
      "new_mode": 33188,
      "new_path": "js/private/watch/src/aspect_watch_protocol.mts"
    }
  ]
}
