When using Durable Object Facets to spawn child servers, you must provide an explicit id in the FacetStartupOptions.
If you omit the id, the facet inherits the parent's ctx.id.name, causing this.name to return the parent's name instead of the child's. To ensure the child has its own identity and that this.name works correctly, construct the ID using the namespace's idFromName() method.
Note: Do not use plain strings as IDs (e.g., id: "child-foo"). This causes the facet to behave like idFromString, which lacks a ctx.id.name and will cause this.name to throw.
import { Server } from "partyserver";
export class FacetChild extends Server {
// `this.name` here will report `facetName` (NOT the parent's name)
// because we passed an explicit `id` at spawn time below.
onStart() {
console.log("facet started:", this.name);
}
}
export class ParentServer extends Server {
async fetch(request: Request) {
const facetName = "child-foo";
// Recommended: construct the id via `ctx.exports[BoundDOClass]`,
// which is also a `DurableObjectNamespace`. Any bound DO class
// works — the id is opaque + a name; nothing routes through the
// namespace at runtime for facets.
const id = this.ctx.exports.ParentServer.idFromName(facetName);
const facet = this.ctx.facets.get(facetName, () => ({
class: this.ctx.exports.FacetChild,
id // <-- the critical bit
}));
return facet.fetch(request);
}
}