Writes a restored id onto an already-constructed node (§79, 2026-08-06
A-17) — the seam for a nodeFactory that built the node itself and so could
not pass NodeOptions.id to a constructor.
Prefer the constructor option: it is checked, it needs no mutation of a
readonly field, and it is available to every node class. This function
exists because @fourjs/serialization's nodeFactory contract lets an
application construct its own classes with no id parameter at all, and §79
still requires those nodes to reload under their saved ids.
It lives here, in the module that owns the field, rather than in the
package that needs it: Node.id is readonly in the type system and an
ordinary writable own property at runtime (a class field under
useDefineForClassFields), so writing it is a cast — and a cast at a foreign
class's field is exactly what a package boundary should not contain. The id
is reserved on the way through, so the counter cannot re-issue it.
Writes a restored id onto an already-constructed node (§79, 2026-08-06 A-17) — the seam for a
nodeFactorythat built the node itself and so could not pass NodeOptions.id to a constructor.Prefer the constructor option: it is checked, it needs no mutation of a
readonlyfield, and it is available to every node class. This function exists because@fourjs/serialization'snodeFactorycontract lets an application construct its own classes with no id parameter at all, and §79 still requires those nodes to reload under their saved ids.It lives here, in the module that owns the field, rather than in the package that needs it:
Node.idisreadonlyin the type system and an ordinary writable own property at runtime (a class field underuseDefineForClassFields), so writing it is a cast — and a cast at a foreign class's field is exactly what a package boundary should not contain. The id is reserved on the way through, so the counter cannot re-issue it.