NodeAccessorPlugin spec does not deduplicate
<!-- Before opening an issue: if you use `npm` try running `yarn` instead; if
      you run `yarn`, please try running `npx yarn-deduplicate && yarn`. -->

### Summary

When using the `xByNodeId` queries, the plan does not correctly deduplicate equivalent constants.

![Screenshot 2025-01-06 at 11 52 37 AM](https://github.com/user-attachments/assets/41b1f90d-c100-48da-9055-ae548ce8bf59)

### Steps to reproduce

Setup Postgraphile v5 with the relay preset. Add a table with the ability to do a root query to fetch a single row of that table by its node ID. e.g.

```sql
create table foo (id int primary key, a text);
```

Set `graphile.explain` to `true` in your preset

Execute a query in Ruru using aliases to query the same row twice. e.g.

```gql
query MyFoos {
  foo1: fooById(id="asdfasdf") {
    id
  }
  foo2: fooById(id="asdfasdf") {
    id
  }
}
```

See the diagram of the plan is similar to the screenshot above

If necessary, I can create a minimal repro of this, but it's probably not necessary, because I'd like to tackle the issue, and I have a repro on my project 🙂

### Expected results

I'd expect to see only a single Lambda step

### Actual results

I see two Lambda steps

### Additional context

Discussed here

https://discord.com/channels/489127045289476126/1325736426587033652/1325877404559740959

### Possible Solution

According to @benjie, the specForHandler function [here](https://github.com/graphile/crystal/blob/00d79e6f5608affc3f36bb0ce4ca2547230174e7/graphile-build/graphile-build/src/plugins/NodeAccessorPlugin.ts#L61-L76) incorrectly returns a new function each time. Thus the [lambda() here](https://github.com/graphile/crystal/blob/00d79e6f5608affc3f36bb0ce4ca2547230174e7/graphile-build/graphile-build/src/plugins/NodeAccessorPlugin.ts#L93) cannot deduplicate because the functions are not equivalent. We could potentially cache the function in a Map such that the functions are equivalent, and lambda() can deduplicate