fix(desktop): preserve binding wrappers after lazy op upgrade (#36065)
Closes #36033.
## Problem
`DESKTOP_JS` wraps `BrowserWindow.prototype.bind`, `unbind`, and
`Tray.prototype.destroy` to maintain JavaScript-side callback and object
registries.
Fast-call op installation is deferred until the first residual extension
module is loaded. `Deno.serve()` triggers that upgrade, which
unconditionally replaced the cppgc prototype methods and overwrote the
JavaScript wrappers. The native binding name still reached the desktop
backend, but the callback was no longer recorded in
`windowBindCallbacks`, so renderer calls failed with `No callback bound
for: ping`.
## Fix
- Register the native bind, unbind, and tray-destroy primitives on
internal `Symbol.for(...)` slots.
- Keep the public string-named methods as JavaScript wrappers.
- Resolve the symbol-backed primitive dynamically when forwarding, so
calls use the original slow op before deferred installation and the
upgraded fast op afterward.
- Add tests pinning the separation between public wrapper names and fast
symbol-backed native methods.
This avoids disabling fast calls and does not force the whole deferred
fast-op pass to run eagerly during desktop startup.
## Validation
- `cargo test -p deno_runtime ops::desktop::tests`
- `cargo test -p denort desktop::tests`
- `./tools/format.js --check`
- `cargo build -p deno -p denort_desktop`
- Reproduced the issue with matched debug `target/debug/deno` and
`target/debug/libdenort.dylib` using `deno desktop --hmr -RN bug.ts`:
the handler logged `handler invoked` and the desktop window rendered
`pong`.