import { handler, NAME, pattern, SELF, type Stream, UI, type VNode, } from "commonfabric"; interface Input { title: string; items: string[]; } interface Output { [NAME]: string; [UI]: VNode; title: string; items: string[]; other: unknown; otherTitle: string; shouted: string; echoed: string[]; kept: string[]; bound: unknown; poke: Stream; } const Child = pattern<{ room: unknown }, { [UI]: VNode }>(() => ({ [UI]: child, })); const poke = handler((_, { room }) => { console.log(room); }); // FIXTURE: pattern-input-self-index // Verifies: `input[SELF]` in the pattern body reads the pattern's own result // in place, the way a destructured `[SELF]` binding does // input[SELF] → input[__cfHelpers.SELF] // input[SELF].title → input[__cfHelpers.SELF].key("title") // const self = input[SELF] → const self = input[__cfHelpers.SELF] // input[SELF].title + "!" → lift over input[__cfHelpers.SELF].key("title") // poke({ room: input[SELF] }) → poke({ room: input[__cfHelpers.SELF] }) // input[SELF].items.map(fn) → input[__cfHelpers.SELF].key("items").mapWithPattern(...) // input[SELF].items.filter(fn) → input[__cfHelpers.SELF].key("items").filterWithPattern(...) // const { [SELF]: s } = input → const s = input[__cfHelpers.SELF] // input[SELF].title.toUpperCase() → lift capturing input[SELF].title // Context: `SELF` adds no `$SELF` path to the pattern's input schema export default pattern((input) => { const self = input[SELF]; const { [SELF]: bound } = input; return { [NAME]: "Input SELF", [UI]: (
{input[SELF].title} {input[SELF].title + "!"}
), title: input.title, items: input.items, other: input[SELF], otherTitle: input[SELF].title, shouted: input[SELF].title.toUpperCase(), echoed: input[SELF].items.map((item) => item + "!"), kept: input[SELF].items.filter((item) => item !== "b"), bound, poke: poke({ room: input[SELF] }), }; });