UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

65 lines (58 loc) 1.98 kB
/** * Unbound port placeholders for deferred `definePorts(...)` keys. * * Ports declared as deferred boot as marked placeholders. Any method call on * a placeholder throws a descriptive error, and `createServer(...)` scans * final ports after provider startup so a missing provider fails boot instead * of failing on first use. */ const UNBOUND_PORT_MARKER = Symbol.for("beignet.unboundPort"); function unboundPortMessage(portName: string): string { return ( `Port "${portName}" is not bound. "${portName}" is declared as deferred ` + "in definePorts(...). Register a provider that contributes it " + "(server/providers.ts) or bind it in infra/port-wiring.ts." ); } /** * Create a marked placeholder for a deferred port. * * Property access returns a function that throws, so calling any method on an * unbound port produces a descriptive error naming the port. */ export function createUnboundPort(portName: string): unknown { return new Proxy( {}, { get(_target, property) { if (property === UNBOUND_PORT_MARKER) return true; if (property === Symbol.toStringTag) { return `UnboundPort(${portName})`; } // Keep unbound ports safe to `await` and JSON-serialize. if (property === "then" || property === "toJSON") return undefined; if (typeof property === "symbol") return undefined; if (property === "toString") { return () => `[unbound port "${portName}"]`; } return () => { throw new Error(unboundPortMessage(portName)); }; }, }, ); } /** * Check whether a value is an unbound port placeholder created for a deferred * `definePorts(...)` key. */ export function isUnboundPort(value: unknown): boolean { if (value === null || typeof value !== "object") return false; try { return ( (value as Record<PropertyKey, unknown>)[UNBOUND_PORT_MARKER] === true ); } catch { return false; } }