/** * The PORTED half: the host's own component, rewritten into the screen dialect. * * The body is the host's, byte for byte. Only the module's IMPORTS move, and * every one of them moves the same way: the host's local name survives as a * generated SHIM, so a call the host wrote (`useRewards(accountId)`) still * reads exactly like that in the port while its body becomes the one capability * the dialect has. A remix is edited by a model, and a model that has to * re-derive the host's call sites is a model rewriting working code. * * Placement is ALL-OR-NOTHING per import statement, and that is the whole * conservatism of this file: one binding the port cannot place leaves the * statement written as the host wrote it, so the gauntlet refuses the port and * NAMES the module. There is no second, cheaper opinion about what is portable * here — the check that governs a remix at save time is the check that decides * whether one can exist. */ /** One host import the port replaced with a generated capability. */ export interface PortBinding { /** The local name the host wrote — the port keeps calling it by that name. */ name: string; /** The name its module exports it under; "default" for a default import. */ imported: string; /** The specifier the host wrote, for the caller to resolve. */ specifier: string; } export interface Port { /** Every render-time read, bundled into ONE envelope tool: the engine resolves * a screen's data as one result per tool, so a component's reads have to * arrive together or they cannot all be served. `arity` is the widest CALL * the host component makes of each hook — the same ceiling the writes carry. */ read?: { tool: string; bindings: Array; }; /** One intent per action binding — reachable only from a handler. `arity` is * the widest CALL the host component actually makes, which is the ceiling on * what the generated tool may accept. */ writes: Array<{ tool: string; binding: PortBinding; arity: number; }>; holes: PortBinding[]; /** The host's own module with its imports cut out, and the default export the * dialect needs. Kept apart from the shims because a shim cannot be written * until the host's SIGNATURE is resolved — see {@link renderPort}. */ body: string; trailer: string; } /** `RewardsPanel` -> `rewards_panel`, `payBill` -> `pay_bill`. */ export declare const snakeName: (name: string) => string; export declare const readToolName: (slot: string) => string; export declare const writeToolName: (slot: string, binding: string) => string; /** Null when the host's compiler could not read the module — never a guess. */ export declare function portComponent(slot: string, source: string, file: string): Port | null; /** * The ported TSX, once the host's signatures are known. * * Separate from {@link portComponent} because a shim cannot be written before * its host function is resolved: it keeps the call site's arguments under the * host's OWN parameter names, so that the generated tool's input is the * original call's shape rather than an open bag. * * `parameters` maps a binding name to the parameter names its tool accepts, in * order — exactly as wide as the host component's own widest call. */ export declare function renderPort(port: Port, parameters: ReadonlyMap, /** Names the CARVER added to the screen surface: its holes, and the Kit * Button when a host `