@opentui/solid
Advanced tools
| { | ||
| "version": 3, | ||
| "sources": ["src/elements/catalogue.ts"], | ||
| "sourcesContent": [ | ||
| "import {\n ASCIIFontRenderable,\n BoxRenderable,\n CodeRenderable,\n DiffRenderable,\n InputRenderable,\n LineNumberRenderable,\n MarkdownRenderable,\n ScrollBoxRenderable,\n SelectRenderable,\n TabSelectRenderable,\n TextareaRenderable,\n TextAttributes,\n TextNodeRenderable,\n TextRenderable,\n type RenderContext,\n type TextNodeOptions,\n} from \"@opentui/core\"\nimport type { RenderableConstructor } from \"../types/elements.js\"\n\nclass SpanRenderable extends TextNodeRenderable {\n constructor(\n private readonly _ctx: RenderContext | null,\n options: TextNodeOptions,\n ) {\n super(options)\n }\n}\n\nexport const textNodeKeys = [\"span\", \"b\", \"strong\", \"i\", \"em\", \"u\", \"a\"] as const\nexport type TextNodeKey = (typeof textNodeKeys)[number]\n\nclass TextModifierRenderable extends SpanRenderable {\n constructor(options: any, modifier?: TextNodeKey) {\n super(null, options)\n\n // Set appropriate attributes based on modifier type\n if (modifier === \"b\" || modifier === \"strong\") {\n this.attributes = (this.attributes || 0) | TextAttributes.BOLD\n } else if (modifier === \"i\" || modifier === \"em\") {\n this.attributes = (this.attributes || 0) | TextAttributes.ITALIC\n } else if (modifier === \"u\") {\n this.attributes = (this.attributes || 0) | TextAttributes.UNDERLINE\n }\n }\n}\n\nexport class BoldSpanRenderable extends TextModifierRenderable {\n constructor(options: any) {\n super(options, \"b\")\n }\n}\n\nexport class ItalicSpanRenderable extends TextModifierRenderable {\n constructor(options: any) {\n super(options, \"i\")\n }\n}\n\nexport class UnderlineSpanRenderable extends TextModifierRenderable {\n constructor(options: any) {\n super(options, \"u\")\n }\n}\n\nexport class LineBreakRenderable extends SpanRenderable {\n constructor(_ctx: RenderContext | null, options: TextNodeOptions) {\n super(null, options)\n this.add()\n }\n\n public override add(): number {\n return super.add(\"\\n\")\n }\n}\n\nexport interface LinkOptions extends TextNodeOptions {\n href: string\n}\n\nexport class LinkRenderable extends SpanRenderable {\n constructor(_ctx: RenderContext | null, options: LinkOptions) {\n const linkOptions: TextNodeOptions = {\n ...options,\n link: { url: options.href },\n }\n super(null, linkOptions)\n }\n}\n\nexport const baseComponents = {\n box: BoxRenderable,\n text: TextRenderable,\n input: InputRenderable,\n select: SelectRenderable,\n textarea: TextareaRenderable,\n ascii_font: ASCIIFontRenderable,\n tab_select: TabSelectRenderable,\n scrollbox: ScrollBoxRenderable,\n code: CodeRenderable,\n diff: DiffRenderable,\n line_number: LineNumberRenderable,\n markdown: MarkdownRenderable,\n\n span: SpanRenderable,\n strong: BoldSpanRenderable,\n b: BoldSpanRenderable,\n em: ItalicSpanRenderable,\n i: ItalicSpanRenderable,\n u: UnderlineSpanRenderable,\n br: LineBreakRenderable,\n a: LinkRenderable,\n}\n\ntype ComponentCatalogue = Record<string, RenderableConstructor>\n\nexport const componentCatalogue: ComponentCatalogue = { ...baseComponents }\n\n/**\n * Extend the component catalogue with new renderable components\n *\n * @example\n * ```tsx\n * // Extend with an object of components\n * extend({\n * consoleButton: ButtonRenderable,\n * customBox: CustomBoxRenderable\n * })\n * ```\n */\nexport function extend<T extends ComponentCatalogue>(objects: T): void {\n Object.assign(componentCatalogue, objects)\n}\n\nexport function getComponentCatalogue(): ComponentCatalogue {\n return componentCatalogue\n}\n\nexport type { ExtendedComponentProps, ExtendedIntrinsicElements, RenderableConstructor } from \"../types/elements.js\"\n" | ||
| ], | ||
| "mappings": ";AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBA,MAAM,uBAAuB,mBAAmB;AAAA,EAE3B;AAAA,EADnB,WAAW,CACQ,MACjB,SACA;AAAA,IACA,MAAM,OAAO;AAAA,IAHI;AAAA;AAKrB;AAKA,MAAM,+BAA+B,eAAe;AAAA,EAClD,WAAW,CAAC,SAAc,UAAwB;AAAA,IAChD,MAAM,MAAM,OAAO;AAAA,IAGnB,IAAI,aAAa,OAAO,aAAa,UAAU;AAAA,MAC7C,KAAK,cAAc,KAAK,cAAc,KAAK,eAAe;AAAA,IAC5D,EAAO,SAAI,aAAa,OAAO,aAAa,MAAM;AAAA,MAChD,KAAK,cAAc,KAAK,cAAc,KAAK,eAAe;AAAA,IAC5D,EAAO,SAAI,aAAa,KAAK;AAAA,MAC3B,KAAK,cAAc,KAAK,cAAc,KAAK,eAAe;AAAA,IAC5D;AAAA;AAEJ;AAAA;AAEO,MAAM,2BAA2B,uBAAuB;AAAA,EAC7D,WAAW,CAAC,SAAc;AAAA,IACxB,MAAM,SAAS,GAAG;AAAA;AAEtB;AAAA;AAEO,MAAM,6BAA6B,uBAAuB;AAAA,EAC/D,WAAW,CAAC,SAAc;AAAA,IACxB,MAAM,SAAS,GAAG;AAAA;AAEtB;AAAA;AAEO,MAAM,gCAAgC,uBAAuB;AAAA,EAClE,WAAW,CAAC,SAAc;AAAA,IACxB,MAAM,SAAS,GAAG;AAAA;AAEtB;AAAA;AAEO,MAAM,4BAA4B,eAAe;AAAA,EACtD,WAAW,CAAC,MAA4B,SAA0B;AAAA,IAChE,MAAM,MAAM,OAAO;AAAA,IACnB,KAAK,IAAI;AAAA;AAAA,EAGK,GAAG,GAAW;AAAA,IAC5B,OAAO,MAAM,IAAI;AAAA,CAAI;AAAA;AAEzB;AAAA;AAMO,MAAM,uBAAuB,eAAe;AAAA,EACjD,WAAW,CAAC,MAA4B,SAAsB;AAAA,IAC5D,MAAM,cAA+B;AAAA,SAChC;AAAA,MACH,MAAM,EAAE,KAAK,QAAQ,KAAK;AAAA,IAC5B;AAAA,IACA,MAAM,MAAM,WAAW;AAAA;AAE3B;AAEO,IAAM,iBAAiB;AAAA,EAC5B,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AAAA,EAEV,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AAAA,EACH,GAAG;AAAA,EACH,IAAI;AAAA,EACJ,GAAG;AACL;AAIO,IAAM,qBAAyC,KAAK,eAAe;AAcnE,SAAS,MAAoC,CAAC,SAAkB;AAAA,EACrE,OAAO,OAAO,oBAAoB,OAAO;AAAA;AAGpC,SAAS,qBAAqB,GAAuB;AAAA,EAC1D,OAAO;AAAA;", | ||
| "debugId": "4D3EF7806518248664756E2164756E21", | ||
| "names": [] | ||
| } |
+1609
| // @bun | ||
| // index.ts | ||
| import { CliRenderer, createCliRenderer, engine as engine2 } from "@opentui/core"; | ||
| import { createTestRenderer } from "@opentui/core/testing"; | ||
| // src/elements/catalogue.ts | ||
| import { | ||
| ASCIIFontRenderable, | ||
| BoxRenderable, | ||
| CodeRenderable, | ||
| DiffRenderable, | ||
| InputRenderable, | ||
| LineNumberRenderable, | ||
| MarkdownRenderable, | ||
| ScrollBoxRenderable, | ||
| SelectRenderable, | ||
| TabSelectRenderable, | ||
| TextareaRenderable, | ||
| TextAttributes, | ||
| TextNodeRenderable, | ||
| TextRenderable | ||
| } from "@opentui/core"; | ||
| class SpanRenderable extends TextNodeRenderable { | ||
| _ctx; | ||
| constructor(_ctx, options) { | ||
| super(options); | ||
| this._ctx = _ctx; | ||
| } | ||
| } | ||
| var textNodeKeys = ["span", "b", "strong", "i", "em", "u", "a"]; | ||
| class TextModifierRenderable extends SpanRenderable { | ||
| constructor(options, modifier) { | ||
| super(null, options); | ||
| if (modifier === "b" || modifier === "strong") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.BOLD; | ||
| } else if (modifier === "i" || modifier === "em") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.ITALIC; | ||
| } else if (modifier === "u") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.UNDERLINE; | ||
| } | ||
| } | ||
| } | ||
| class BoldSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "b"); | ||
| } | ||
| } | ||
| class ItalicSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "i"); | ||
| } | ||
| } | ||
| class UnderlineSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "u"); | ||
| } | ||
| } | ||
| class LineBreakRenderable extends SpanRenderable { | ||
| constructor(_ctx, options) { | ||
| super(null, options); | ||
| this.add(); | ||
| } | ||
| add() { | ||
| return super.add(` | ||
| `); | ||
| } | ||
| } | ||
| class LinkRenderable extends SpanRenderable { | ||
| constructor(_ctx, options) { | ||
| const linkOptions = { | ||
| ...options, | ||
| link: { url: options.href } | ||
| }; | ||
| super(null, linkOptions); | ||
| } | ||
| } | ||
| var baseComponents = { | ||
| box: BoxRenderable, | ||
| text: TextRenderable, | ||
| input: InputRenderable, | ||
| select: SelectRenderable, | ||
| textarea: TextareaRenderable, | ||
| ascii_font: ASCIIFontRenderable, | ||
| tab_select: TabSelectRenderable, | ||
| scrollbox: ScrollBoxRenderable, | ||
| code: CodeRenderable, | ||
| diff: DiffRenderable, | ||
| line_number: LineNumberRenderable, | ||
| markdown: MarkdownRenderable, | ||
| span: SpanRenderable, | ||
| strong: BoldSpanRenderable, | ||
| b: BoldSpanRenderable, | ||
| em: ItalicSpanRenderable, | ||
| i: ItalicSpanRenderable, | ||
| u: UnderlineSpanRenderable, | ||
| br: LineBreakRenderable, | ||
| a: LinkRenderable | ||
| }; | ||
| var componentCatalogue = { ...baseComponents }; | ||
| function extend(objects) { | ||
| Object.assign(componentCatalogue, objects); | ||
| } | ||
| function getComponentCatalogue() { | ||
| return componentCatalogue; | ||
| } | ||
| // src/elements/hooks.ts | ||
| import { | ||
| engine, | ||
| Timeline | ||
| } from "@opentui/core"; | ||
| import { createContext, createSignal, onCleanup, onMount, useContext } from "solid-js"; | ||
| var RendererContext = createContext(); | ||
| var useRenderer = () => { | ||
| const renderer = useContext(RendererContext); | ||
| if (!renderer) { | ||
| throw new Error("No renderer found"); | ||
| } | ||
| return renderer; | ||
| }; | ||
| var onResize = (callback) => { | ||
| const renderer = useRenderer(); | ||
| onMount(() => { | ||
| renderer.on("resize", callback); | ||
| }); | ||
| onCleanup(() => { | ||
| renderer.off("resize", callback); | ||
| }); | ||
| }; | ||
| var useTerminalDimensions = () => { | ||
| const renderer = useRenderer(); | ||
| const [terminalDimensions, setTerminalDimensions] = createSignal({ width: renderer.width, height: renderer.height }); | ||
| const callback = (width, height) => { | ||
| setTerminalDimensions({ width, height }); | ||
| }; | ||
| onResize(callback); | ||
| return terminalDimensions; | ||
| }; | ||
| var useKeyboard = (callback, options) => { | ||
| const renderer = useRenderer(); | ||
| const keyHandler = renderer.keyInput; | ||
| onMount(() => { | ||
| keyHandler.on("keypress", callback); | ||
| if (options?.release) { | ||
| keyHandler.on("keyrelease", callback); | ||
| } | ||
| }); | ||
| onCleanup(() => { | ||
| keyHandler.off("keypress", callback); | ||
| if (options?.release) { | ||
| keyHandler.off("keyrelease", callback); | ||
| } | ||
| }); | ||
| }; | ||
| var usePaste = (callback) => { | ||
| const renderer = useRenderer(); | ||
| const keyHandler = renderer.keyInput; | ||
| onMount(() => { | ||
| keyHandler.on("paste", callback); | ||
| }); | ||
| onCleanup(() => { | ||
| keyHandler.off("paste", callback); | ||
| }); | ||
| }; | ||
| var useKeyHandler = useKeyboard; | ||
| var onFocus = (callback) => { | ||
| const renderer = useRenderer(); | ||
| onMount(() => { | ||
| renderer.on("focus", callback); | ||
| }); | ||
| onCleanup(() => { | ||
| renderer.off("focus", callback); | ||
| }); | ||
| }; | ||
| var onBlur = (callback) => { | ||
| const renderer = useRenderer(); | ||
| onMount(() => { | ||
| renderer.on("blur", callback); | ||
| }); | ||
| onCleanup(() => { | ||
| renderer.off("blur", callback); | ||
| }); | ||
| }; | ||
| var useSelectionHandler = (callback) => { | ||
| const renderer = useRenderer(); | ||
| onMount(() => { | ||
| renderer.on("selection", callback); | ||
| }); | ||
| onCleanup(() => { | ||
| renderer.off("selection", callback); | ||
| }); | ||
| }; | ||
| var useTimeline = (options = {}) => { | ||
| const timeline = new Timeline(options); | ||
| onMount(() => { | ||
| if (options.autoplay !== false) { | ||
| timeline.play(); | ||
| } | ||
| engine.register(timeline); | ||
| }); | ||
| onCleanup(() => { | ||
| timeline.pause(); | ||
| engine.unregister(timeline); | ||
| }); | ||
| return timeline; | ||
| }; | ||
| // src/elements/extras.ts | ||
| import { createEffect, createMemo as createMemo2, getOwner, onCleanup as onCleanup2, runWithOwner, splitProps, untrack as untrack2 } from "solid-js"; | ||
| // src/reconciler.ts | ||
| import { | ||
| BaseRenderable, | ||
| createTextAttributes, | ||
| InputRenderable as InputRenderable2, | ||
| InputRenderableEvents, | ||
| isTextNodeRenderable, | ||
| parseColor, | ||
| Renderable, | ||
| RootTextNodeRenderable, | ||
| ScrollBoxRenderable as ScrollBoxRenderable2, | ||
| SelectRenderable as SelectRenderable2, | ||
| SelectRenderableEvents, | ||
| TabSelectRenderable as TabSelectRenderable2, | ||
| TabSelectRenderableEvents, | ||
| TextNodeRenderable as TextNodeRenderable2, | ||
| TextRenderable as TextRenderable2 | ||
| } from "@opentui/core"; | ||
| import { decodeHTML } from "entities"; | ||
| import { useContext as useContext2 } from "solid-js"; | ||
| // src/renderer/universal.js | ||
| import { createRoot, createRenderEffect, createMemo, createComponent, untrack, mergeProps } from "solid-js"; | ||
| var memo = (fn) => createMemo(() => fn()); | ||
| function createRenderer({ | ||
| createElement, | ||
| createTextNode, | ||
| createSlotNode, | ||
| isTextNode, | ||
| replaceText, | ||
| insertNode, | ||
| removeNode, | ||
| setProperty, | ||
| getParentNode, | ||
| getFirstChild, | ||
| getNextSibling | ||
| }) { | ||
| function insert(parent, accessor, marker, initial) { | ||
| if (marker !== undefined && !initial) | ||
| initial = []; | ||
| if (typeof accessor !== "function") | ||
| return insertExpression(parent, accessor, initial, marker); | ||
| createRenderEffect((current) => insertExpression(parent, accessor(), current, marker), initial); | ||
| } | ||
| function insertExpression(parent, value, current, marker, unwrapArray) { | ||
| while (typeof current === "function") | ||
| current = current(); | ||
| if (value === current) | ||
| return current; | ||
| const t = typeof value, multi = marker !== undefined; | ||
| if (t === "string" || t === "number") { | ||
| if (t === "number") | ||
| value = value.toString(); | ||
| if (multi) { | ||
| let node = current[0]; | ||
| if (node && isTextNode(node)) { | ||
| replaceText(node, value); | ||
| } else | ||
| node = createTextNode(value); | ||
| current = cleanChildren(parent, current, marker, node); | ||
| } else { | ||
| if (current !== "" && typeof current === "string") { | ||
| replaceText(getFirstChild(parent), current = value); | ||
| } else { | ||
| cleanChildren(parent, current, marker, createTextNode(value)); | ||
| current = value; | ||
| } | ||
| } | ||
| } else if (value == null || t === "boolean") { | ||
| current = cleanChildren(parent, current, marker); | ||
| } else if (t === "function") { | ||
| createRenderEffect(() => { | ||
| let v = value(); | ||
| while (typeof v === "function") | ||
| v = v(); | ||
| current = insertExpression(parent, v, current, marker); | ||
| }); | ||
| return () => current; | ||
| } else if (Array.isArray(value)) { | ||
| const array = []; | ||
| if (normalizeIncomingArray(array, value, unwrapArray)) { | ||
| createRenderEffect(() => current = insertExpression(parent, array, current, marker, true)); | ||
| return () => current; | ||
| } | ||
| if (array.length === 0) { | ||
| const replacement = cleanChildren(parent, current, marker); | ||
| if (multi) | ||
| return current = replacement; | ||
| } else { | ||
| if (Array.isArray(current)) { | ||
| if (current.length === 0) { | ||
| appendNodes(parent, array, marker); | ||
| } else | ||
| reconcileArrays(parent, current, array); | ||
| } else if (current == null || current === "") { | ||
| appendNodes(parent, array); | ||
| } else { | ||
| reconcileArrays(parent, multi && current || [getFirstChild(parent)], array); | ||
| } | ||
| } | ||
| current = array; | ||
| } else { | ||
| if (Array.isArray(current)) { | ||
| if (multi) | ||
| return current = cleanChildren(parent, current, marker, value); | ||
| cleanChildren(parent, current, null, value); | ||
| } else if (current == null || current === "" || !getFirstChild(parent)) { | ||
| insertNode(parent, value); | ||
| } else | ||
| replaceNode(parent, value, getFirstChild(parent)); | ||
| current = value; | ||
| } | ||
| return current; | ||
| } | ||
| function normalizeIncomingArray(normalized, array, unwrap) { | ||
| let dynamic = false; | ||
| for (let i = 0, len = array.length;i < len; i++) { | ||
| let item = array[i], t; | ||
| if (item == null || item === true || item === false) | ||
| ; | ||
| else if (Array.isArray(item)) { | ||
| dynamic = normalizeIncomingArray(normalized, item) || dynamic; | ||
| } else if ((t = typeof item) === "string" || t === "number") { | ||
| normalized.push(createTextNode(item)); | ||
| } else if (t === "function") { | ||
| if (unwrap) { | ||
| while (typeof item === "function") | ||
| item = item(); | ||
| dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item]) || dynamic; | ||
| } else { | ||
| normalized.push(item); | ||
| dynamic = true; | ||
| } | ||
| } else | ||
| normalized.push(item); | ||
| } | ||
| return dynamic; | ||
| } | ||
| function reconcileArrays(parentNode, a, b) { | ||
| let bLength = b.length, aEnd = a.length, bEnd = bLength, aStart = 0, bStart = 0, after = getNextSibling(a[aEnd - 1]), map = null; | ||
| while (aStart < aEnd || bStart < bEnd) { | ||
| if (a[aStart] === b[bStart]) { | ||
| aStart++; | ||
| bStart++; | ||
| continue; | ||
| } | ||
| while (a[aEnd - 1] === b[bEnd - 1]) { | ||
| aEnd--; | ||
| bEnd--; | ||
| } | ||
| if (aEnd === aStart) { | ||
| const node = bEnd < bLength ? bStart ? getNextSibling(b[bStart - 1]) : b[bEnd - bStart] : after; | ||
| while (bStart < bEnd) | ||
| insertNode(parentNode, b[bStart++], node); | ||
| } else if (bEnd === bStart) { | ||
| while (aStart < aEnd) { | ||
| if (!map || !map.has(a[aStart])) | ||
| removeNode(parentNode, a[aStart]); | ||
| aStart++; | ||
| } | ||
| } else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) { | ||
| const node = getNextSibling(a[--aEnd]); | ||
| insertNode(parentNode, b[bStart++], getNextSibling(a[aStart++])); | ||
| insertNode(parentNode, b[--bEnd], node); | ||
| a[aEnd] = b[bEnd]; | ||
| } else { | ||
| if (!map) { | ||
| map = new Map; | ||
| let i = bStart; | ||
| while (i < bEnd) | ||
| map.set(b[i], i++); | ||
| } | ||
| const index = map.get(a[aStart]); | ||
| if (index != null) { | ||
| if (bStart < index && index < bEnd) { | ||
| let i = aStart, sequence = 1, t; | ||
| while (++i < aEnd && i < bEnd) { | ||
| if ((t = map.get(a[i])) == null || t !== index + sequence) | ||
| break; | ||
| sequence++; | ||
| } | ||
| if (sequence > index - bStart) { | ||
| const node = a[aStart]; | ||
| while (bStart < index) | ||
| insertNode(parentNode, b[bStart++], node); | ||
| } else | ||
| replaceNode(parentNode, b[bStart++], a[aStart++]); | ||
| } else | ||
| aStart++; | ||
| } else | ||
| removeNode(parentNode, a[aStart++]); | ||
| } | ||
| } | ||
| } | ||
| function cleanChildren(parent, current, marker, replacement) { | ||
| if (marker === undefined) { | ||
| let removed; | ||
| while (removed = getFirstChild(parent)) | ||
| removeNode(parent, removed); | ||
| replacement && insertNode(parent, replacement); | ||
| return replacement ?? ""; | ||
| } | ||
| const node = replacement || createSlotNode(); | ||
| if (current.length) { | ||
| let inserted = false; | ||
| for (let i = current.length - 1;i >= 0; i--) { | ||
| const el = current[i]; | ||
| if (node !== el) { | ||
| const isParent = getParentNode(el) === parent; | ||
| if (!inserted && !i) | ||
| isParent ? replaceNode(parent, node, el) : insertNode(parent, node, marker); | ||
| else | ||
| isParent && removeNode(parent, el); | ||
| } else | ||
| inserted = true; | ||
| } | ||
| } else | ||
| insertNode(parent, node, marker); | ||
| return [node]; | ||
| } | ||
| function appendNodes(parent, array, marker) { | ||
| for (let i = 0, len = array.length;i < len; i++) | ||
| insertNode(parent, array[i], marker); | ||
| } | ||
| function replaceNode(parent, newNode, oldNode) { | ||
| insertNode(parent, newNode, oldNode); | ||
| removeNode(parent, oldNode); | ||
| } | ||
| function spreadExpression(node, props, prevProps = {}, skipChildren) { | ||
| props || (props = {}); | ||
| if (!skipChildren) { | ||
| createRenderEffect(() => prevProps.children = insertExpression(node, props.children, prevProps.children)); | ||
| } | ||
| createRenderEffect(() => props.ref && props.ref(node)); | ||
| createRenderEffect(() => { | ||
| for (const prop in props) { | ||
| if (prop === "children" || prop === "ref") | ||
| continue; | ||
| const value = props[prop]; | ||
| if (value === prevProps[prop]) | ||
| continue; | ||
| setProperty(node, prop, value, prevProps[prop]); | ||
| prevProps[prop] = value; | ||
| } | ||
| }); | ||
| return prevProps; | ||
| } | ||
| return { | ||
| render(code, element) { | ||
| let disposer; | ||
| createRoot((dispose) => { | ||
| disposer = dispose; | ||
| insert(element, code()); | ||
| }); | ||
| return disposer; | ||
| }, | ||
| insert, | ||
| spread(node, accessor, skipChildren) { | ||
| if (typeof accessor === "function") { | ||
| createRenderEffect((current) => spreadExpression(node, accessor(), current, skipChildren)); | ||
| } else | ||
| spreadExpression(node, accessor, undefined, skipChildren); | ||
| }, | ||
| createElement, | ||
| createTextNode, | ||
| insertNode, | ||
| setProp(node, name, value, prev) { | ||
| setProperty(node, name, value, prev); | ||
| return value; | ||
| }, | ||
| mergeProps, | ||
| effect: createRenderEffect, | ||
| memo, | ||
| createComponent, | ||
| use(fn, element, arg) { | ||
| return untrack(() => fn(element, arg)); | ||
| } | ||
| }; | ||
| } | ||
| // src/renderer/index.ts | ||
| import { mergeProps as mergeProps2 } from "solid-js"; | ||
| function createRenderer2(options) { | ||
| const renderer = createRenderer(options); | ||
| renderer.mergeProps = mergeProps2; | ||
| return renderer; | ||
| } | ||
| // src/utils/id-counter.ts | ||
| var idCounter = new Map; | ||
| function getNextId(elementType) { | ||
| if (!idCounter.has(elementType)) { | ||
| idCounter.set(elementType, 0); | ||
| } | ||
| const value = idCounter.get(elementType) + 1; | ||
| idCounter.set(elementType, value); | ||
| return `${elementType}-${value}`; | ||
| } | ||
| // src/utils/log.ts | ||
| var log = (...args) => { | ||
| if (process.env.DEBUG) { | ||
| console.log("[Reconciler]", ...args); | ||
| } | ||
| }; | ||
| // src/reconciler.ts | ||
| class TextNode extends TextNodeRenderable2 { | ||
| static fromString(text, options = {}) { | ||
| const node = new TextNode(options); | ||
| node.add(text); | ||
| return node; | ||
| } | ||
| } | ||
| var logId = (node) => { | ||
| if (!node) | ||
| return; | ||
| return node.id; | ||
| }; | ||
| var getNodeChildren = (node) => { | ||
| let children; | ||
| if (node instanceof TextRenderable2) { | ||
| children = node.getTextChildren(); | ||
| } else { | ||
| children = node.getChildren(); | ||
| } | ||
| return children; | ||
| }; | ||
| function _insertNode(parent, node, anchor) { | ||
| log("Inserting node:", logId(node), "into parent:", logId(parent), "with anchor:", logId(anchor), node instanceof TextNode); | ||
| if (node instanceof SlotRenderable) { | ||
| node.parent = parent; | ||
| node = node.getSlotChild(parent); | ||
| } | ||
| if (anchor && anchor instanceof SlotRenderable) { | ||
| anchor = anchor.getSlotChild(parent); | ||
| } | ||
| if (isTextNodeRenderable(node)) { | ||
| if (!(parent instanceof TextRenderable2) && !isTextNodeRenderable(parent)) { | ||
| throw new Error(`Orphan text error: "${node.toChunks().map((c) => c.text).join("")}" must have a <text> as a parent: ${parent.id} above ${node.id}`); | ||
| } | ||
| } | ||
| if (!(parent instanceof BaseRenderable)) { | ||
| console.error("[INSERT]", "Tried to mount a non base renderable"); | ||
| throw new Error("Tried to mount a non base renderable"); | ||
| } | ||
| if (!anchor) { | ||
| parent.add(node); | ||
| return; | ||
| } | ||
| const children = getNodeChildren(parent); | ||
| const anchorIndex = children.findIndex((el) => el.id === anchor.id); | ||
| if (anchorIndex === -1) { | ||
| log("[INSERT]", "Could not find anchor", logId(parent), logId(anchor), "[children]", ...children.map((c) => c.id)); | ||
| } | ||
| parent.add(node, anchorIndex); | ||
| } | ||
| function _removeNode(parent, node) { | ||
| log("Removing node:", logId(node), "from parent:", logId(parent)); | ||
| let slotParent; | ||
| if (node instanceof SlotRenderable) { | ||
| slotParent = node; | ||
| const slotChild = slotParent.getSlotChildForRemoval(parent); | ||
| if (!slotChild) { | ||
| if (slotParent.parent === parent) { | ||
| slotParent.parent = null; | ||
| } | ||
| return; | ||
| } | ||
| node = slotChild; | ||
| } | ||
| parent.remove(node.id); | ||
| slotParent?.didRemoveSlotChild(parent, node); | ||
| process.nextTick(() => { | ||
| if (node instanceof BaseRenderable && !node.parent) { | ||
| node.destroyRecursively(); | ||
| return; | ||
| } | ||
| }); | ||
| } | ||
| function _createTextNode(value) { | ||
| log("Creating text node:", value); | ||
| const id = getNextId("text-node"); | ||
| if (typeof value === "number") { | ||
| value = value.toString(); | ||
| } | ||
| return TextNode.fromString(decodeHTML(value), { id }); | ||
| } | ||
| function createSlotNode() { | ||
| const id = getNextId("slot-node"); | ||
| log("Creating slot node", id); | ||
| return new SlotRenderable(id); | ||
| } | ||
| function _getParentNode(childNode) { | ||
| log("Getting parent of node:", logId(childNode)); | ||
| let parent = childNode.parent ?? undefined; | ||
| if (parent instanceof RootTextNodeRenderable) { | ||
| parent = parent.textParent ?? undefined; | ||
| } | ||
| const scrollBoxCandidate = parent?.parent?.parent?.parent; | ||
| if (scrollBoxCandidate instanceof ScrollBoxRenderable2 && scrollBoxCandidate.content === parent) { | ||
| parent = scrollBoxCandidate; | ||
| } | ||
| return parent; | ||
| } | ||
| var { | ||
| render: _render, | ||
| effect, | ||
| memo: memo2, | ||
| createComponent: createComponent2, | ||
| createElement, | ||
| createTextNode, | ||
| insertNode, | ||
| insert, | ||
| spread, | ||
| setProp, | ||
| mergeProps: mergeProps3, | ||
| use | ||
| } = createRenderer2({ | ||
| createElement(tagName) { | ||
| log("Creating element:", tagName); | ||
| const id = getNextId(tagName); | ||
| const solidRenderer = useContext2(RendererContext); | ||
| if (!solidRenderer) { | ||
| throw new Error("No renderer found"); | ||
| } | ||
| const elements = getComponentCatalogue(); | ||
| if (!elements[tagName]) { | ||
| throw new Error(`[Reconciler] Unknown component type: ${tagName}`); | ||
| } | ||
| const element = new elements[tagName](solidRenderer, { id }); | ||
| log("Element created with id:", id); | ||
| return element; | ||
| }, | ||
| createTextNode: _createTextNode, | ||
| createSlotNode, | ||
| replaceText(textNode, value) { | ||
| log("Replacing text:", value, "in node:", logId(textNode)); | ||
| if (!(textNode instanceof TextNode)) | ||
| return; | ||
| textNode.replace(decodeHTML(value), 0); | ||
| }, | ||
| setProperty(node, name, value, prev) { | ||
| if (name.startsWith("on:")) { | ||
| const eventName = name.slice(3); | ||
| if (value) { | ||
| node.on(eventName, value); | ||
| } | ||
| if (prev) { | ||
| node.off(eventName, prev); | ||
| } | ||
| return; | ||
| } | ||
| if (isTextNodeRenderable(node)) { | ||
| if (name === "href") { | ||
| node.link = { url: value }; | ||
| return; | ||
| } | ||
| if (name === "style") { | ||
| node.attributes |= createTextAttributes(value); | ||
| node.fg = value.fg ? parseColor(value.fg) : node.fg; | ||
| node.bg = value.bg ? parseColor(value.bg) : node.bg; | ||
| return; | ||
| } | ||
| return; | ||
| } | ||
| switch (name) { | ||
| case "id": | ||
| log("Id mapped", node.id, "=", value); | ||
| node[name] = value; | ||
| break; | ||
| case "focused": | ||
| if (!(node instanceof Renderable)) | ||
| return; | ||
| if (value) { | ||
| node.focus(); | ||
| } else { | ||
| node.blur(); | ||
| } | ||
| break; | ||
| case "onChange": | ||
| let event = undefined; | ||
| if (node instanceof SelectRenderable2) { | ||
| event = SelectRenderableEvents.SELECTION_CHANGED; | ||
| } else if (node instanceof TabSelectRenderable2) { | ||
| event = TabSelectRenderableEvents.SELECTION_CHANGED; | ||
| } else if (node instanceof InputRenderable2) { | ||
| event = InputRenderableEvents.CHANGE; | ||
| } | ||
| if (!event) | ||
| break; | ||
| if (value) { | ||
| node.on(event, value); | ||
| } | ||
| if (prev) { | ||
| node.off(event, prev); | ||
| } | ||
| break; | ||
| case "onInput": | ||
| if (node instanceof InputRenderable2) { | ||
| if (value) { | ||
| node.on(InputRenderableEvents.INPUT, value); | ||
| } | ||
| if (prev) { | ||
| node.off(InputRenderableEvents.INPUT, prev); | ||
| } | ||
| } | ||
| break; | ||
| case "onSubmit": | ||
| if (node instanceof InputRenderable2) { | ||
| if (value) { | ||
| node.on(InputRenderableEvents.ENTER, value); | ||
| } | ||
| if (prev) { | ||
| node.off(InputRenderableEvents.ENTER, prev); | ||
| } | ||
| } else { | ||
| node[name] = value; | ||
| } | ||
| break; | ||
| case "onSelect": | ||
| if (node instanceof SelectRenderable2) { | ||
| if (value) { | ||
| node.on(SelectRenderableEvents.ITEM_SELECTED, value); | ||
| } | ||
| if (prev) { | ||
| node.off(SelectRenderableEvents.ITEM_SELECTED, prev); | ||
| } | ||
| } else if (node instanceof TabSelectRenderable2) { | ||
| if (value) { | ||
| node.on(TabSelectRenderableEvents.ITEM_SELECTED, value); | ||
| } | ||
| if (prev) { | ||
| node.off(TabSelectRenderableEvents.ITEM_SELECTED, prev); | ||
| } | ||
| } | ||
| break; | ||
| case "style": | ||
| for (const prop in value) { | ||
| const propVal = value[prop]; | ||
| if (prev !== undefined && propVal === prev[prop]) | ||
| continue; | ||
| node[prop] = propVal; | ||
| } | ||
| break; | ||
| case "text": | ||
| case "content": { | ||
| const textValue = typeof value === "string" ? value : Array.isArray(value) ? value.join("") : `${value}`; | ||
| node[name] = decodeHTML(textValue); | ||
| break; | ||
| } | ||
| default: | ||
| node[name] = value; | ||
| } | ||
| }, | ||
| isTextNode(node) { | ||
| return node instanceof TextNode; | ||
| }, | ||
| insertNode: _insertNode, | ||
| removeNode: _removeNode, | ||
| getParentNode: _getParentNode, | ||
| getFirstChild(node) { | ||
| log("Getting first child of node:", logId(node)); | ||
| const firstChild = getNodeChildren(node)[0]; | ||
| if (!firstChild) { | ||
| log("No first child found for node:", logId(node)); | ||
| return; | ||
| } | ||
| log("First child found:", logId(firstChild), "for node:", logId(node)); | ||
| return firstChild; | ||
| }, | ||
| getNextSibling(node) { | ||
| log("Getting next sibling of node:", logId(node)); | ||
| const parent = _getParentNode(node); | ||
| if (!parent) { | ||
| log("No parent found for node:", logId(node)); | ||
| return; | ||
| } | ||
| if (node instanceof SlotRenderable) { | ||
| const layoutSlotNode = node.getSlotChildForRemoval(parent); | ||
| if (layoutSlotNode) { | ||
| node = layoutSlotNode; | ||
| } | ||
| } | ||
| const siblings = getNodeChildren(parent); | ||
| const index = siblings.indexOf(node); | ||
| if (index === -1 || index === siblings.length - 1) { | ||
| log("No next sibling found for node:", logId(node)); | ||
| return; | ||
| } | ||
| const nextSibling = siblings[index + 1]; | ||
| if (!nextSibling) { | ||
| log("Next sibling is null for node:", logId(node)); | ||
| return; | ||
| } | ||
| log("Next sibling found:", logId(nextSibling), "for node:", logId(node)); | ||
| return nextSibling; | ||
| } | ||
| }); | ||
| // src/elements/extras.ts | ||
| function Portal(props) { | ||
| const renderer = useRenderer(); | ||
| const marker = createSlotNode(), mount = () => props.mount || renderer.root, owner = getOwner(); | ||
| let content; | ||
| createEffect(() => { | ||
| content || (content = runWithOwner(owner, () => createMemo2(() => props.children))); | ||
| const el = mount(); | ||
| const container = createElement("box"), renderRoot = container; | ||
| Object.defineProperty(container, "_$host", { | ||
| get() { | ||
| return marker.parent; | ||
| }, | ||
| configurable: true | ||
| }); | ||
| insert(renderRoot, content); | ||
| el.add(container); | ||
| props.ref && props.ref(container); | ||
| onCleanup2(() => el.remove(container.id)); | ||
| }, undefined, { render: true }); | ||
| return marker; | ||
| } | ||
| function createDynamic(component, props) { | ||
| const cached = createMemo2(component); | ||
| return createMemo2(() => { | ||
| const component2 = cached(); | ||
| switch (typeof component2) { | ||
| case "function": | ||
| return untrack2(() => component2(props)); | ||
| case "string": | ||
| const el = createElement(component2); | ||
| spread(el, props); | ||
| return el; | ||
| default: | ||
| break; | ||
| } | ||
| }); | ||
| } | ||
| function Dynamic(props) { | ||
| const [, others] = splitProps(props, ["component"]); | ||
| return createDynamic(() => props.component, others); | ||
| } | ||
| // src/elements/slot.ts | ||
| import { BaseRenderable as BaseRenderable2, isTextNodeRenderable as isTextNodeRenderable2, TextNodeRenderable as TextNodeRenderable3, TextRenderable as TextRenderable3, Yoga } from "@opentui/core"; | ||
| function getLayoutNodeConstructor(parent) { | ||
| const parentLayoutNode = parent?.getLayoutNode?.(); | ||
| return parentLayoutNode?.constructor; | ||
| } | ||
| function createLayoutSlotYogaNode(parentNodeConstructor) { | ||
| return parentNodeConstructor?.create?.() ?? Yoga.default.Node.create(); | ||
| } | ||
| class SlotBaseRenderable extends BaseRenderable2 { | ||
| constructor(id) { | ||
| super({ | ||
| id | ||
| }); | ||
| } | ||
| add(obj, index) { | ||
| throw new Error("Can't add children on an Slot renderable"); | ||
| } | ||
| getChildren() { | ||
| return []; | ||
| } | ||
| remove(id) {} | ||
| insertBefore(obj, anchor) { | ||
| throw new Error("Can't add children on an Slot renderable"); | ||
| } | ||
| getRenderable(id) { | ||
| return; | ||
| } | ||
| getChildrenCount() { | ||
| return 0; | ||
| } | ||
| requestRender() {} | ||
| findDescendantById(id) { | ||
| return; | ||
| } | ||
| } | ||
| class TextSlotRenderable extends TextNodeRenderable3 { | ||
| slotParent; | ||
| destroyed = false; | ||
| constructor(id, parent) { | ||
| super({ id }); | ||
| this._visible = false; | ||
| this.slotParent = parent; | ||
| } | ||
| detachFromSlot() { | ||
| this.slotParent = undefined; | ||
| } | ||
| disposeWithoutSlotCascade() { | ||
| if (this.destroyed) { | ||
| return; | ||
| } | ||
| this.destroyed = true; | ||
| this.detachFromSlot(); | ||
| } | ||
| destroy() { | ||
| if (this.destroyed) { | ||
| return; | ||
| } | ||
| this.destroyed = true; | ||
| const slotParent = this.slotParent; | ||
| this.slotParent = undefined; | ||
| slotParent?.destroy(); | ||
| super.destroy(); | ||
| } | ||
| } | ||
| class LayoutSlotRenderable extends SlotBaseRenderable { | ||
| yogaNode; | ||
| slotParent; | ||
| destroyed = false; | ||
| yogaNodeConstructor; | ||
| yogaNodeFreed = false; | ||
| constructor(id, parent, layoutParent) { | ||
| super(id); | ||
| this._visible = false; | ||
| this.slotParent = parent; | ||
| this.yogaNodeConstructor = getLayoutNodeConstructor(layoutParent); | ||
| this.yogaNode = createLayoutSlotYogaNode(this.yogaNodeConstructor); | ||
| this.yogaNode.setDisplay(Yoga.Display.None); | ||
| } | ||
| getLayoutNode() { | ||
| return this.yogaNode; | ||
| } | ||
| updateFromLayout() {} | ||
| updateLayout() {} | ||
| onRemove() {} | ||
| isCompatibleWith(layoutParent) { | ||
| return this.yogaNodeConstructor === getLayoutNodeConstructor(layoutParent); | ||
| } | ||
| detachFromSlot() { | ||
| this.slotParent = undefined; | ||
| } | ||
| freeYogaNode() { | ||
| if (this.yogaNodeFreed) { | ||
| return; | ||
| } | ||
| this.yogaNodeFreed = true; | ||
| try { | ||
| this.yogaNode.free(); | ||
| } catch {} | ||
| } | ||
| disposeWithoutSlotCascade() { | ||
| if (this.destroyed) { | ||
| return; | ||
| } | ||
| this.destroyed = true; | ||
| this.detachFromSlot(); | ||
| this.freeYogaNode(); | ||
| } | ||
| destroy() { | ||
| if (this.destroyed) { | ||
| return; | ||
| } | ||
| this.destroyed = true; | ||
| const slotParent = this.slotParent; | ||
| this.slotParent = undefined; | ||
| this.freeYogaNode(); | ||
| slotParent?.destroy(); | ||
| } | ||
| } | ||
| class SlotRenderable extends SlotBaseRenderable { | ||
| destroyed = false; | ||
| layoutNodesByParent = new Map; | ||
| textNodesByParent = new Map; | ||
| layoutNodeCount = 0; | ||
| textNodeCount = 0; | ||
| constructor(id) { | ||
| super(id); | ||
| this._visible = false; | ||
| } | ||
| get layoutNode() { | ||
| return this.getCurrentSlotChild(this.layoutNodesByParent); | ||
| } | ||
| get textNode() { | ||
| return this.getCurrentSlotChild(this.textNodesByParent); | ||
| } | ||
| isTextSlotParent(parent) { | ||
| return isTextNodeRenderable2(parent) || parent instanceof TextRenderable3; | ||
| } | ||
| getCurrentSlotChild(nodesByParent) { | ||
| for (const node of nodesByParent.values()) { | ||
| if (node.parent) { | ||
| return node; | ||
| } | ||
| } | ||
| return nodesByParent.values().next().value; | ||
| } | ||
| getTextNodeForParent(parent) { | ||
| const mappedNode = this.textNodesByParent.get(parent); | ||
| if (mappedNode) { | ||
| return mappedNode; | ||
| } | ||
| for (const [mappedParent, textNode] of this.textNodesByParent) { | ||
| if (textNode.parent !== parent) { | ||
| continue; | ||
| } | ||
| this.textNodesByParent.delete(mappedParent); | ||
| this.textNodesByParent.set(parent, textNode); | ||
| return textNode; | ||
| } | ||
| } | ||
| getLayoutNodeForParent(parent) { | ||
| const mappedNode = this.layoutNodesByParent.get(parent); | ||
| if (mappedNode) { | ||
| return mappedNode; | ||
| } | ||
| for (const [mappedParent, layoutNode] of this.layoutNodesByParent) { | ||
| if (layoutNode.parent !== parent) { | ||
| continue; | ||
| } | ||
| this.layoutNodesByParent.delete(mappedParent); | ||
| this.layoutNodesByParent.set(parent, layoutNode); | ||
| return layoutNode; | ||
| } | ||
| } | ||
| takeReusableTextNode(parent) { | ||
| for (const [mappedParent, textNode] of this.textNodesByParent) { | ||
| if (textNode.parent) { | ||
| continue; | ||
| } | ||
| this.textNodesByParent.delete(mappedParent); | ||
| this.textNodesByParent.set(parent, textNode); | ||
| return textNode; | ||
| } | ||
| } | ||
| takeReusableLayoutNode(parent) { | ||
| for (const [mappedParent, layoutNode] of this.layoutNodesByParent) { | ||
| if (layoutNode.parent) { | ||
| continue; | ||
| } | ||
| if (!layoutNode.isCompatibleWith(parent)) { | ||
| continue; | ||
| } | ||
| this.layoutNodesByParent.delete(mappedParent); | ||
| this.layoutNodesByParent.set(parent, layoutNode); | ||
| return layoutNode; | ||
| } | ||
| } | ||
| disposeDetachedTextNodes() { | ||
| for (const [parent, textNode] of this.textNodesByParent) { | ||
| if (textNode.parent) { | ||
| continue; | ||
| } | ||
| this.textNodesByParent.delete(parent); | ||
| textNode.disposeWithoutSlotCascade(); | ||
| } | ||
| } | ||
| disposeDetachedIncompatibleLayoutNodes(parent) { | ||
| for (const [mappedParent, layoutNode] of this.layoutNodesByParent) { | ||
| if (layoutNode.parent || layoutNode.isCompatibleWith(parent)) { | ||
| continue; | ||
| } | ||
| this.layoutNodesByParent.delete(mappedParent); | ||
| layoutNode.disposeWithoutSlotCascade(); | ||
| } | ||
| } | ||
| getAttachedSlotParent(excludedNode) { | ||
| for (const textNode of this.textNodesByParent.values()) { | ||
| if (textNode !== excludedNode && textNode.parent) { | ||
| return textNode.parent; | ||
| } | ||
| } | ||
| for (const layoutNode of this.layoutNodesByParent.values()) { | ||
| if (layoutNode !== excludedNode && layoutNode.parent) { | ||
| return layoutNode.parent; | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| hasOtherAttachedSlotChildren(excludedNode) { | ||
| return this.getAttachedSlotParent(excludedNode) !== null; | ||
| } | ||
| getSlotChild(parent) { | ||
| if (this.isTextSlotParent(parent)) { | ||
| const existingTextNode = this.getTextNodeForParent(parent); | ||
| if (existingTextNode) { | ||
| return existingTextNode; | ||
| } | ||
| const reusableTextNode = this.takeReusableTextNode(parent); | ||
| if (reusableTextNode) { | ||
| return reusableTextNode; | ||
| } | ||
| this.disposeDetachedIncompatibleLayoutNodes(parent); | ||
| const textNode = new TextSlotRenderable(`slot-text-${this.id}-${++this.textNodeCount}`, this); | ||
| this.textNodesByParent.set(parent, textNode); | ||
| return textNode; | ||
| } | ||
| const existingLayoutNode = this.getLayoutNodeForParent(parent); | ||
| if (existingLayoutNode) { | ||
| return existingLayoutNode; | ||
| } | ||
| const reusableLayoutNode = this.takeReusableLayoutNode(parent); | ||
| if (reusableLayoutNode) { | ||
| return reusableLayoutNode; | ||
| } | ||
| this.disposeDetachedTextNodes(); | ||
| this.disposeDetachedIncompatibleLayoutNodes(parent); | ||
| const layoutNode = new LayoutSlotRenderable(`slot-layout-${this.id}-${++this.layoutNodeCount}`, this, parent); | ||
| this.layoutNodesByParent.set(parent, layoutNode); | ||
| return layoutNode; | ||
| } | ||
| getSlotChildForRemoval(parent) { | ||
| if (this.isTextSlotParent(parent)) { | ||
| return this.getTextNodeForParent(parent); | ||
| } | ||
| return this.getLayoutNodeForParent(parent); | ||
| } | ||
| didRemoveSlotChild(parent, child) { | ||
| const hasOtherAttachedSlotChildren = this.hasOtherAttachedSlotChildren(child); | ||
| if (hasOtherAttachedSlotChildren && child instanceof TextSlotRenderable && this.getTextNodeForParent(parent) === child) { | ||
| this.textNodesByParent.delete(parent); | ||
| child.disposeWithoutSlotCascade(); | ||
| } | ||
| if (hasOtherAttachedSlotChildren && child instanceof LayoutSlotRenderable && this.getLayoutNodeForParent(parent) === child) { | ||
| this.layoutNodesByParent.delete(parent); | ||
| child.disposeWithoutSlotCascade(); | ||
| } | ||
| if (this.parent === parent) { | ||
| this.parent = this.getAttachedSlotParent(child); | ||
| } | ||
| } | ||
| destroy() { | ||
| if (this.destroyed) { | ||
| return; | ||
| } | ||
| this.destroyed = true; | ||
| const layoutNodes = new Set(this.layoutNodesByParent.values()); | ||
| this.layoutNodesByParent.clear(); | ||
| for (const layoutNode of layoutNodes) { | ||
| layoutNode.destroy(); | ||
| } | ||
| const textNodes = new Set(this.textNodesByParent.values()); | ||
| this.textNodesByParent.clear(); | ||
| for (const textNode of textNodes) { | ||
| textNode.destroy(); | ||
| } | ||
| } | ||
| } | ||
| // src/scrollback.ts | ||
| import { | ||
| BoxRenderable as BoxRenderable2, | ||
| RootRenderable | ||
| } from "@opentui/core"; | ||
| import { createSignal as createSignal2 } from "solid-js"; | ||
| var solidScrollbackRootCounter = 0; | ||
| var MAX_AUTO_HEIGHT_PASSES = 4; | ||
| function normalizeSnapshotDimension(value, axis) { | ||
| if (value === undefined) { | ||
| return; | ||
| } | ||
| if (!Number.isFinite(value)) { | ||
| throw new Error(`createScrollbackWriter requires a finite ${axis}`); | ||
| } | ||
| return Math.max(1, Math.trunc(value)); | ||
| } | ||
| function createSnapshotRendererValue(renderContext, root, width, height, firstLineOffset) { | ||
| const [snapshotWidth] = createSignal2(width); | ||
| const [snapshotHeight, setSnapshotHeight] = createSignal2(height); | ||
| const renderer = Object.create(renderContext); | ||
| let offset = firstLineOffset; | ||
| Object.defineProperties(renderer, { | ||
| root: { | ||
| value: root, | ||
| enumerable: true, | ||
| configurable: true | ||
| }, | ||
| width: { | ||
| get: snapshotWidth, | ||
| enumerable: true, | ||
| configurable: true | ||
| }, | ||
| height: { | ||
| get: snapshotHeight, | ||
| enumerable: true, | ||
| configurable: true | ||
| }, | ||
| claimFirstLineOffset: { | ||
| value: () => { | ||
| const out = offset; | ||
| offset = 0; | ||
| return out; | ||
| }, | ||
| enumerable: true, | ||
| configurable: true | ||
| } | ||
| }); | ||
| return { | ||
| renderer, | ||
| getHeight: snapshotHeight, | ||
| setHeight(nextHeight) { | ||
| setSnapshotHeight(nextHeight); | ||
| renderer.emit("resize", snapshotWidth(), nextHeight); | ||
| } | ||
| }; | ||
| } | ||
| function runLifecyclePasses(renderContext) { | ||
| for (const renderable of renderContext.getLifecyclePasses()) { | ||
| renderable.onLifecyclePass?.call(renderable); | ||
| } | ||
| } | ||
| function clearLifecyclePasses(renderContext) { | ||
| for (const renderable of [...renderContext.getLifecyclePasses()]) { | ||
| renderContext.unregisterLifecyclePass(renderable); | ||
| } | ||
| } | ||
| function measureSnapshotHeight(renderContext, root) { | ||
| const measureRoot = new RootRenderable(renderContext); | ||
| try { | ||
| measureRoot.add(root); | ||
| runLifecyclePasses(renderContext); | ||
| measureRoot.calculateLayout(); | ||
| return Math.max(1, Math.trunc(root.getLayoutNode().getComputedLayout().height)); | ||
| } finally { | ||
| if (root.parent === measureRoot) { | ||
| measureRoot.remove(root.id); | ||
| } | ||
| measureRoot.destroyRecursively(); | ||
| } | ||
| } | ||
| function resolveSnapshotHeight(renderContext, root, snapshotRenderer) { | ||
| for (let pass = 0;pass < MAX_AUTO_HEIGHT_PASSES; pass++) { | ||
| const measuredHeight = measureSnapshotHeight(renderContext, root); | ||
| if (measuredHeight === snapshotRenderer.getHeight()) { | ||
| clearLifecyclePasses(renderContext); | ||
| return measuredHeight; | ||
| } | ||
| snapshotRenderer.setHeight(measuredHeight); | ||
| } | ||
| return measureSnapshotHeight(renderContext, root); | ||
| } | ||
| function createScrollbackWriter(node, options = {}) { | ||
| return (ctx) => { | ||
| const width = normalizeSnapshotDimension(options.width, "width") ?? Math.max(1, Math.trunc(ctx.width)); | ||
| const height = normalizeSnapshotDimension(options.height, "height"); | ||
| const startOnNewLine = options.startOnNewLine ?? true; | ||
| const firstLineWidth = !startOnNewLine && ctx.tailColumn > 0 && ctx.tailColumn < ctx.width ? Math.min(width, ctx.width - ctx.tailColumn) : width; | ||
| const firstLineOffset = width - firstLineWidth; | ||
| const root = new BoxRenderable2(ctx.renderContext, { | ||
| id: `solid-scrollback-root-${solidScrollbackRootCounter++}`, | ||
| position: "absolute", | ||
| left: 0, | ||
| top: 0, | ||
| width, | ||
| height: height ?? "auto", | ||
| border: false, | ||
| backgroundColor: "transparent", | ||
| shouldFill: false, | ||
| flexDirection: "column" | ||
| }); | ||
| const snapshotRenderer = createSnapshotRendererValue(ctx.renderContext, root, width, height ?? Math.max(1, ctx.renderContext.height), firstLineOffset); | ||
| let dispose; | ||
| let disposed = false; | ||
| const teardown = () => { | ||
| if (disposed) { | ||
| return; | ||
| } | ||
| disposed = true; | ||
| dispose?.(); | ||
| }; | ||
| try { | ||
| dispose = _render(() => createComponent2(RendererContext.Provider, { | ||
| get value() { | ||
| return snapshotRenderer.renderer; | ||
| }, | ||
| get children() { | ||
| return node(ctx); | ||
| } | ||
| }), root); | ||
| return { | ||
| root, | ||
| width, | ||
| height: height ?? resolveSnapshotHeight(ctx.renderContext, root, snapshotRenderer), | ||
| rowColumns: options.rowColumns, | ||
| startOnNewLine, | ||
| trailingNewline: options.trailingNewline, | ||
| teardown | ||
| }; | ||
| } catch (error) { | ||
| teardown(); | ||
| root.destroyRecursively(); | ||
| throw error; | ||
| } | ||
| }; | ||
| } | ||
| function writeSolidToScrollback(renderer, node, options = {}) { | ||
| renderer.writeToScrollback(createScrollbackWriter(node, options)); | ||
| } | ||
| // src/time-to-first-draw.tsx | ||
| import { TimeToFirstDrawRenderable } from "@opentui/core"; | ||
| extend({ | ||
| time_to_first_draw: TimeToFirstDrawRenderable | ||
| }); | ||
| var TimeToFirstDraw = (props) => { | ||
| return (() => { | ||
| var _el$ = createElement("time_to_first_draw"); | ||
| spread(_el$, props, false); | ||
| return _el$; | ||
| })(); | ||
| }; | ||
| // src/plugins/slot.tsx | ||
| import { createSlotRegistry } from "@opentui/core"; | ||
| import { children, createMemo as createMemo3, createSignal as createSignal3, ErrorBoundary, For, onCleanup as onCleanup3, splitProps as splitProps2 } from "solid-js"; | ||
| var EMPTY_ENTRY_IDS = []; | ||
| function createSolidSlotRegistry(renderer, context, options = {}) { | ||
| return createSlotRegistry(renderer, "solid:slot-registry", context, options); | ||
| } | ||
| function createSlot(registry, options = {}) { | ||
| return function BoundSlot(props) { | ||
| return createComponent2(Slot, mergeProps3(props, { | ||
| registry, | ||
| get pluginFailurePlaceholder() { | ||
| return options.pluginFailurePlaceholder; | ||
| } | ||
| })); | ||
| }; | ||
| } | ||
| function Slot(props) { | ||
| const [local, slotProps] = splitProps2(props, ["registry", "name", "mode", "children", "pluginFailurePlaceholder"]); | ||
| const registry = () => local.registry; | ||
| const pluginFailurePlaceholder = () => local.pluginFailurePlaceholder; | ||
| const [version, setVersion] = createSignal3(0); | ||
| let queued = false; | ||
| let disposed = false; | ||
| const unsubscribe = registry().subscribe(() => { | ||
| if (queued) | ||
| return; | ||
| queued = true; | ||
| setVersion((current) => current + 1); | ||
| queueMicrotask(() => { | ||
| queued = false; | ||
| if (disposed) | ||
| return; | ||
| }); | ||
| }); | ||
| onCleanup3(() => { | ||
| disposed = true; | ||
| unsubscribe(); | ||
| }); | ||
| const entries = createMemo3((previousEntries = []) => { | ||
| version(); | ||
| const resolvedEntries = registry().resolveEntries(local.name); | ||
| if (resolvedEntries.length === 0) { | ||
| if (previousEntries.length === 0) | ||
| return previousEntries; | ||
| return []; | ||
| } | ||
| const previousById = new Map(previousEntries.map((entry) => [entry.id, entry])); | ||
| const nextEntries = resolvedEntries.map((entry) => { | ||
| const previousEntry = previousById.get(entry.id); | ||
| if (previousEntry && previousEntry.renderer === entry.renderer) { | ||
| return previousEntry; | ||
| } | ||
| return entry; | ||
| }); | ||
| const unchanged = nextEntries.length === previousEntries.length && nextEntries.every((entry, index) => entry === previousEntries[index]); | ||
| if (unchanged) | ||
| return previousEntries; | ||
| return nextEntries; | ||
| }); | ||
| const entryIds = createMemo3(() => entries().map((entry) => entry.id)); | ||
| const entriesById = createMemo3(() => new Map(entries().map((entry) => [entry.id, entry]))); | ||
| const slotName = () => String(local.name); | ||
| const renderFallback = () => { | ||
| const value = children(() => local.children)(); | ||
| return value ?? null; | ||
| }; | ||
| const resolveFallback = (fallbackValue) => fallbackValue?.() ?? null; | ||
| const renderPluginFailurePlaceholder = (failure, fallbackValue) => { | ||
| if (!pluginFailurePlaceholder()) { | ||
| return resolveFallback(fallbackValue); | ||
| } | ||
| try { | ||
| return pluginFailurePlaceholder()(failure); | ||
| } catch (error) { | ||
| registry().reportPluginError({ | ||
| pluginId: failure.pluginId, | ||
| slot: failure.slot ?? slotName(), | ||
| phase: "error_placeholder", | ||
| source: "solid", | ||
| error | ||
| }); | ||
| return resolveFallback(fallbackValue); | ||
| } | ||
| }; | ||
| const renderEntry = (entry, fallbackOnError) => { | ||
| let initialRender; | ||
| try { | ||
| initialRender = entry.renderer(registry().context, slotProps); | ||
| } catch (error) { | ||
| const failure = registry().reportPluginError({ | ||
| pluginId: entry.id, | ||
| slot: slotName(), | ||
| phase: "render", | ||
| source: "solid", | ||
| error | ||
| }); | ||
| return renderPluginFailurePlaceholder(failure, fallbackOnError); | ||
| } | ||
| const resolvedInitialRender = children(() => initialRender); | ||
| const hasInitialOutput = resolvedInitialRender.toArray().some((node) => node !== null && node !== undefined && node !== false); | ||
| if (!hasInitialOutput) { | ||
| return resolveFallback(fallbackOnError); | ||
| } | ||
| return createComponent2(ErrorBoundary, { | ||
| fallback: (error) => { | ||
| const failure = registry().reportPluginError({ | ||
| pluginId: entry.id, | ||
| slot: slotName(), | ||
| phase: "render", | ||
| source: "solid", | ||
| error | ||
| }); | ||
| return renderPluginFailurePlaceholder(failure, fallbackOnError); | ||
| }, | ||
| get children() { | ||
| return resolvedInitialRender(); | ||
| } | ||
| }); | ||
| }; | ||
| const AppendEntry = (appendProps) => { | ||
| const entry = createMemo3(() => entriesById().get(appendProps.entryId)); | ||
| return memo2(() => { | ||
| const resolvedEntry = entry(); | ||
| if (!resolvedEntry) { | ||
| return null; | ||
| } | ||
| return renderEntry(resolvedEntry); | ||
| }); | ||
| }; | ||
| const appendEntryIds = createMemo3(() => { | ||
| const mode = local.mode ?? "append"; | ||
| if (mode !== "append") { | ||
| return EMPTY_ENTRY_IDS; | ||
| } | ||
| return entryIds(); | ||
| }); | ||
| const appendView = [renderFallback, createComponent2(For, { | ||
| get each() { | ||
| return appendEntryIds(); | ||
| }, | ||
| children: (entryId) => createComponent2(AppendEntry, { | ||
| entryId | ||
| }) | ||
| })]; | ||
| return memo2(() => { | ||
| const resolvedEntries = entries(); | ||
| const mode = local.mode ?? "append"; | ||
| if (resolvedEntries.length === 0) { | ||
| return renderFallback(); | ||
| } | ||
| if (mode === "single_winner") { | ||
| const winner = resolvedEntries[0]; | ||
| if (!winner) { | ||
| return renderFallback(); | ||
| } | ||
| return renderEntry(winner, renderFallback); | ||
| } | ||
| if (mode === "replace") { | ||
| const renderedEntries = resolvedEntries.map((entry) => renderEntry(entry)); | ||
| const hasPluginOutput = renderedEntries.some((entry) => entry !== null && entry !== undefined && entry !== false); | ||
| if (!hasPluginOutput) { | ||
| return renderFallback(); | ||
| } | ||
| return renderedEntries; | ||
| } | ||
| return appendView; | ||
| }); | ||
| } | ||
| // index.ts | ||
| var mountSolidRoot = (renderer, node) => { | ||
| let dispose; | ||
| let disposeRequested = false; | ||
| let disposed = false; | ||
| let mounting = true; | ||
| let destroyRequested = false; | ||
| const originalDestroy = renderer.destroy.bind(renderer); | ||
| const runDispose = () => { | ||
| if (disposed) { | ||
| return; | ||
| } | ||
| if (!dispose) { | ||
| disposeRequested = true; | ||
| return; | ||
| } | ||
| disposed = true; | ||
| dispose(); | ||
| }; | ||
| renderer.once("destroy", runDispose); | ||
| renderer.destroy = () => { | ||
| if (mounting) { | ||
| destroyRequested = true; | ||
| return; | ||
| } | ||
| originalDestroy(); | ||
| }; | ||
| try { | ||
| dispose = _render(() => createComponent2(RendererContext.Provider, { | ||
| get value() { | ||
| return renderer; | ||
| }, | ||
| get children() { | ||
| return createComponent2(node, {}); | ||
| } | ||
| }), renderer.root); | ||
| } finally { | ||
| mounting = false; | ||
| renderer.destroy = originalDestroy; | ||
| } | ||
| if (disposeRequested) { | ||
| runDispose(); | ||
| } | ||
| if (destroyRequested) { | ||
| originalDestroy(); | ||
| } | ||
| }; | ||
| var render = async (node, rendererOrConfig = {}) => { | ||
| const renderer = rendererOrConfig instanceof CliRenderer ? rendererOrConfig : await createCliRenderer({ | ||
| ...rendererOrConfig, | ||
| onDestroy: () => { | ||
| rendererOrConfig.onDestroy?.(); | ||
| } | ||
| }); | ||
| engine2.attach(renderer); | ||
| mountSolidRoot(renderer, node); | ||
| }; | ||
| var testRender = async (node, renderConfig = {}) => { | ||
| const testSetup = await createTestRenderer({ | ||
| ...renderConfig, | ||
| onDestroy: () => { | ||
| renderConfig.onDestroy?.(); | ||
| } | ||
| }); | ||
| engine2.attach(testSetup.renderer); | ||
| mountSolidRoot(testSetup.renderer, node); | ||
| return testSetup; | ||
| }; | ||
| export { | ||
| writeSolidToScrollback, | ||
| useTimeline, | ||
| useTerminalDimensions, | ||
| useSelectionHandler, | ||
| useRenderer, | ||
| usePaste, | ||
| useKeyboard, | ||
| useKeyHandler, | ||
| use, | ||
| textNodeKeys, | ||
| testRender, | ||
| spread, | ||
| setProp, | ||
| render, | ||
| onResize, | ||
| onFocus, | ||
| onBlur, | ||
| mergeProps3 as mergeProps, | ||
| memo2 as memo, | ||
| insertNode, | ||
| insert, | ||
| getComponentCatalogue, | ||
| extend, | ||
| effect, | ||
| createTextNode, | ||
| createSolidSlotRegistry, | ||
| createSlotNode, | ||
| createSlot, | ||
| createScrollbackWriter, | ||
| createElement, | ||
| createDynamic, | ||
| createComponent2 as createComponent, | ||
| componentCatalogue, | ||
| baseComponents, | ||
| _render, | ||
| UnderlineSpanRenderable, | ||
| TimeToFirstDraw, | ||
| TextSlotRenderable, | ||
| SlotRenderable, | ||
| Slot, | ||
| RendererContext, | ||
| Portal, | ||
| LinkRenderable, | ||
| LineBreakRenderable, | ||
| LayoutSlotRenderable, | ||
| ItalicSpanRenderable, | ||
| Dynamic, | ||
| BoldSpanRenderable | ||
| }; | ||
| //# debugId=E514C995048B172A64756E2164756E21 |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
| export { Fragment, jsxDEV, type JSX } from "./jsx-runtime.js" |
| export { Fragment, jsxDEV } from "./jsx-runtime.js"; | ||
| //# sourceMappingURL=jsx-dev-runtime.js.map |
| {"version":3,"file":"jsx-dev-runtime.js","sourceRoot":"","sources":["jsx-dev-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA"} |
| import { createComponent, createElement, spread } from "@opentui/solid"; | ||
| function normalizeProps(props) { | ||
| if (!props) { | ||
| return {}; | ||
| } | ||
| if (!("key" in props)) { | ||
| return props; | ||
| } | ||
| const { key: _key, ...rest } = props; | ||
| return rest; | ||
| } | ||
| function createIntrinsicElement(type, props) { | ||
| const element = createElement(type); | ||
| spread(element, props); | ||
| return element; | ||
| } | ||
| export function jsx(type, props = {}) { | ||
| const normalizedProps = normalizeProps(props); | ||
| if (typeof type === "function") { | ||
| return createComponent(type, normalizedProps); | ||
| } | ||
| return createIntrinsicElement(type, normalizedProps); | ||
| } | ||
| export const jsxs = jsx; | ||
| export function jsxDEV(type, props = {}) { | ||
| return jsx(type, props); | ||
| } | ||
| export function Fragment(props) { | ||
| return props.children ?? null; | ||
| } | ||
| //# sourceMappingURL=jsx-runtime.js.map |
| {"version":3,"file":"jsx-runtime.js","sourceRoot":"","sources":["jsx-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AA2BvE,SAAS,cAAc,CAAC,KAAkC;IACxD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,CAAA;IACX,CAAC;IAED,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,KAAK,CAAA;IACd,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAA;IACpC,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAS,sBAAsB,CAAC,IAAY,EAAE,KAA8B;IAC1E,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IACnC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IACtB,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,IAA6B,EAAE,QAAyB,EAAE;IAC5E,MAAM,eAAe,GAAG,cAAc,CAAC,KAAK,CAAC,CAAA;IAE7C,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAQ,eAAuB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAA;IACxD,CAAC;IAED,OAAO,sBAAsB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAA;AAEvB,MAAM,UAAU,MAAM,CAAC,IAA6B,EAAE,QAAyB,EAAE;IAC/E,OAAO,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAA6B;IACpD,OAAO,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAA;AAC/B,CAAC"} |
| import { ensureSolidTransformPlugin } from "./solid-plugin.js"; | ||
| ensureSolidTransformPlugin(); | ||
| //# sourceMappingURL=preload.js.map |
| {"version":3,"file":"preload.js","sourceRoot":"","sources":["preload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAA;AAE9D,0BAA0B,EAAE,CAAA"} |
| const errorMessage = "@opentui/solid/preload is Bun-only and is not available in Node.js. Use Bun to import this entrypoint." | ||
| function unavailable() { | ||
| throw new Error(errorMessage) | ||
| } | ||
| unavailable() |
| import { plugin as registerBunPlugin } from "bun"; | ||
| import * as coreRuntime from "@opentui/core"; | ||
| import { createRuntimePlugin, isCoreRuntimeModuleSpecifier, runtimeModuleIdForSpecifier, } from "@opentui/core/runtime-plugin"; | ||
| import * as solidJsRuntime from "solid-js"; | ||
| import * as solidJsStoreRuntime from "solid-js/store"; | ||
| import * as solidRuntime from "@opentui/solid"; | ||
| import { ensureSolidTransformPlugin } from "./solid-plugin.js"; | ||
| const runtimePluginSupportInstalledKey = Symbol.for("opentui.solid.runtime-plugin-support"); | ||
| const defaultRuntimeModules = { | ||
| "@opentui/solid": solidRuntime, | ||
| "solid-js": solidJsRuntime, | ||
| "solid-js/store": solidJsStoreRuntime, | ||
| }; | ||
| function normalizeRewriteKey(rewrite) { | ||
| return `${rewrite?.nodeModulesRuntimeSpecifiers ?? true}:${rewrite?.nodeModulesBareSpecifiers ?? false}`; | ||
| } | ||
| function createRuntimeModules(options) { | ||
| return { | ||
| ...defaultRuntimeModules, | ||
| ...(options?.additional ?? {}), | ||
| }; | ||
| } | ||
| function assertCompatibleInstall(install, modules, options) { | ||
| for (const specifier of Object.keys(modules)) { | ||
| if (!install.specifiers.has(specifier)) { | ||
| throw new Error(`OpenTUI Solid runtime plugin support is already installed without ${specifier}. Call ensureRuntimePluginSupport({ additional }) from @opentui/solid/runtime-plugin-support/configure before importing @opentui/solid/runtime-plugin-support.`); | ||
| } | ||
| } | ||
| if (options?.core && options.core !== install.core) { | ||
| throw new Error("OpenTUI Solid runtime plugin support is already installed with a different core runtime module."); | ||
| } | ||
| if (options?.rewrite && normalizeRewriteKey(options.rewrite) !== install.rewriteKey) { | ||
| throw new Error("OpenTUI Solid runtime plugin support is already installed with different rewrite options."); | ||
| } | ||
| } | ||
| export function ensureRuntimePluginSupport(options = {}) { | ||
| const state = globalThis; | ||
| const modules = createRuntimeModules(options); | ||
| const core = options.core ?? coreRuntime; | ||
| const rewriteKey = normalizeRewriteKey(options.rewrite); | ||
| const install = state[runtimePluginSupportInstalledKey]; | ||
| if (install) { | ||
| assertCompatibleInstall(install, modules, options); | ||
| return false; | ||
| } | ||
| ensureSolidTransformPlugin({ | ||
| moduleName: runtimeModuleIdForSpecifier("@opentui/solid"), | ||
| resolvePath(specifier) { | ||
| if (!isCoreRuntimeModuleSpecifier(specifier) && !modules[specifier]) { | ||
| return null; | ||
| } | ||
| return runtimeModuleIdForSpecifier(specifier); | ||
| }, | ||
| }); | ||
| registerBunPlugin(createRuntimePlugin({ | ||
| core, | ||
| additional: modules, | ||
| rewrite: options.rewrite, | ||
| })); | ||
| state[runtimePluginSupportInstalledKey] = { | ||
| specifiers: new Set(Object.keys(modules)), | ||
| core, | ||
| rewriteKey, | ||
| }; | ||
| return true; | ||
| } | ||
| //# sourceMappingURL=runtime-plugin-support-configure.js.map |
| {"version":3,"file":"runtime-plugin-support-configure.js","sourceRoot":"","sources":["runtime-plugin-support-configure.ts"],"names":[],"mappings":"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"} |
| const errorMessage = "@opentui/solid/runtime-plugin-support/configure is Bun-only and is not available in Node.js. Use Bun to import this entrypoint." | ||
| function unavailable() { | ||
| throw new Error(errorMessage) | ||
| } | ||
| export function ensureRuntimePluginSupport() { | ||
| return unavailable() | ||
| } | ||
| unavailable() |
| import { ensureRuntimePluginSupport } from "./runtime-plugin-support-configure.js"; | ||
| export { ensureRuntimePluginSupport }; | ||
| ensureRuntimePluginSupport(); | ||
| //# sourceMappingURL=runtime-plugin-support.js.map |
| {"version":3,"file":"runtime-plugin-support.js","sourceRoot":"","sources":["runtime-plugin-support.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,uCAAuC,CAAA;AAElF,OAAO,EAAE,0BAA0B,EAAE,CAAA;AAGrC,0BAA0B,EAAE,CAAA"} |
| const errorMessage = "@opentui/solid/runtime-plugin-support is Bun-only and is not available in Node.js. Use Bun to import this entrypoint." | ||
| function unavailable() { | ||
| throw new Error(errorMessage) | ||
| } | ||
| export function ensureRuntimePluginSupport() { | ||
| return unavailable() | ||
| } | ||
| unavailable() |
| import { plugin as registerBunPlugin } from "bun"; | ||
| import { stripQueryAndHash, transformSolidSource } from "./solid-transform.js"; | ||
| const solidTransformStateKey = Symbol.for("opentui.solid.transform"); | ||
| const getSolidTransformState = () => { | ||
| const state = globalThis; | ||
| state[solidTransformStateKey] ??= { installed: false }; | ||
| return state[solidTransformStateKey]; | ||
| }; | ||
| const getSolidTransformRuntime = () => { | ||
| return getSolidTransformState().runtime ?? {}; | ||
| }; | ||
| const hasSolidTransformRuntime = (input) => { | ||
| return input.moduleName !== undefined || input.resolvePath !== undefined; | ||
| }; | ||
| export function ensureSolidTransformPlugin(input = {}) { | ||
| const state = getSolidTransformState(); | ||
| if (hasSolidTransformRuntime(input)) { | ||
| state.runtime = { | ||
| moduleName: input.moduleName, | ||
| resolvePath: input.resolvePath, | ||
| }; | ||
| } | ||
| if (state.installed) { | ||
| return false; | ||
| } | ||
| registerBunPlugin(createSolidTransformPlugin()); | ||
| state.installed = true; | ||
| return true; | ||
| } | ||
| export function resetSolidTransformPluginState() { | ||
| const state = getSolidTransformState(); | ||
| state.installed = false; | ||
| delete state.runtime; | ||
| } | ||
| export function createSolidTransformPlugin(input = {}) { | ||
| const sourceFilter = input.resolvePath | ||
| ? /^(?!.*[/\\]node_modules[/\\]).*\.[cm]?[jt]sx?(?:[?#].*)?$/ | ||
| : /^(?!.*[/\\]node_modules[/\\]).*\.[cm]?[jt]sx(?:[?#].*)?$/; | ||
| return { | ||
| name: "bun-plugin-solid", | ||
| setup: (build) => { | ||
| build.onLoad({ filter: /[/\\]node_modules[/\\]solid-js[/\\]dist[/\\]server\.js(?:[?#].*)?$/ }, async (args) => { | ||
| const path = stripQueryAndHash(args.path).replace("server.js", "solid.js"); | ||
| const file = Bun.file(path); | ||
| const code = await file.text(); | ||
| return { contents: code, loader: "js" }; | ||
| }); | ||
| build.onLoad({ filter: /[/\\]node_modules[/\\]solid-js[/\\]store[/\\]dist[/\\]server\.js(?:[?#].*)?$/ }, async (args) => { | ||
| const path = stripQueryAndHash(args.path).replace("server.js", "store.js"); | ||
| const file = Bun.file(path); | ||
| const code = await file.text(); | ||
| return { contents: code, loader: "js" }; | ||
| }); | ||
| build.onLoad({ filter: sourceFilter }, async (args) => { | ||
| const path = stripQueryAndHash(args.path); | ||
| const file = Bun.file(path); | ||
| const code = await file.text(); | ||
| const runtime = getSolidTransformRuntime(); | ||
| const moduleName = input.moduleName ?? runtime.moduleName ?? "@opentui/solid"; | ||
| const resolvePath = input.resolvePath ?? runtime.resolvePath; | ||
| const contents = await transformSolidSource(code, { | ||
| filename: path, | ||
| moduleName, | ||
| resolvePath, | ||
| }); | ||
| return { | ||
| contents, | ||
| loader: "js", | ||
| }; | ||
| }); | ||
| }, | ||
| }; | ||
| } | ||
| const solidTransformPlugin = createSolidTransformPlugin(); | ||
| export default solidTransformPlugin; | ||
| //# sourceMappingURL=solid-plugin.js.map |
| {"version":3,"file":"solid-plugin.js","sourceRoot":"","sources":["solid-plugin.ts"],"names":[],"mappings":"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"} |
| const errorMessage = "@opentui/solid/bun-plugin is Bun-only and is not available in Node.js. Use Bun to import this entrypoint." | ||
| function unavailable() { | ||
| throw new Error(errorMessage) | ||
| } | ||
| export function ensureSolidTransformPlugin() { | ||
| return unavailable() | ||
| } | ||
| export function resetSolidTransformPluginState() { | ||
| return unavailable() | ||
| } | ||
| export function createSolidTransformPlugin() { | ||
| return unavailable() | ||
| } | ||
| export default unavailable() | ||
| unavailable() |
| export type ResolveImportPath = (specifier: string) => string | null; | ||
| export interface TransformSolidSourceOptions { | ||
| filename: string; | ||
| moduleName?: string; | ||
| resolvePath?: ResolveImportPath; | ||
| } | ||
| export declare function stripQueryAndHash(path: string): string; | ||
| export declare function isNodeModulesPath(path: string): boolean; | ||
| export declare function resolveNodeSolidRuntimeImport(specifier: string): string | null; | ||
| export declare function transformSolidSource(code: string, options: TransformSolidSourceOptions): Promise<string>; |
| import { transformAsync } from "@babel/core"; | ||
| // @ts-expect-error - Types not important. | ||
| import ts from "@babel/preset-typescript"; | ||
| // @ts-expect-error - Types not important. | ||
| import moduleResolver from "babel-plugin-module-resolver"; | ||
| // @ts-expect-error - Types not important. | ||
| import solid from "babel-preset-solid"; | ||
| const nodeModulesPattern = /[/\\]node_modules[/\\]/; | ||
| const tsPattern = /\.[cm]?tsx?$/; | ||
| const jsxPattern = /\.[cm]?[jt]sx$/; | ||
| export function stripQueryAndHash(path) { | ||
| const searchIndex = path.indexOf("?"); | ||
| const hashIndex = path.indexOf("#"); | ||
| const end = [searchIndex, hashIndex].filter((index) => index >= 0).sort((a, b) => a - b)[0]; | ||
| return end === undefined ? path : path.slice(0, end); | ||
| } | ||
| export function isNodeModulesPath(path) { | ||
| return nodeModulesPattern.test(path); | ||
| } | ||
| export function resolveNodeSolidRuntimeImport(specifier) { | ||
| switch (specifier) { | ||
| case "solid-js": | ||
| return "solid-js/dist/solid.js"; | ||
| case "solid-js/store": | ||
| return "solid-js/store/dist/store.js"; | ||
| default: | ||
| return null; | ||
| } | ||
| } | ||
| export async function transformSolidSource(code, options) { | ||
| const filename = stripQueryAndHash(options.filename); | ||
| const plugins = options.resolvePath | ||
| ? [ | ||
| [ | ||
| moduleResolver, | ||
| { | ||
| resolvePath(specifier) { | ||
| return options.resolvePath?.(specifier) ?? specifier; | ||
| }, | ||
| }, | ||
| ], | ||
| ] | ||
| : []; | ||
| const presets = []; | ||
| if (jsxPattern.test(filename)) { | ||
| presets.push([ | ||
| solid, | ||
| { | ||
| moduleName: options.moduleName ?? "@opentui/solid", | ||
| generate: "universal", | ||
| }, | ||
| ]); | ||
| } | ||
| if (tsPattern.test(filename)) { | ||
| presets.push([ts]); | ||
| } | ||
| const transformed = await transformAsync(code, { | ||
| filename, | ||
| configFile: false, | ||
| babelrc: false, | ||
| plugins, | ||
| presets, | ||
| }); | ||
| return transformed?.code ?? code; | ||
| } | ||
| //# sourceMappingURL=solid-transform.js.map |
| {"version":3,"file":"solid-transform.js","sourceRoot":"","sources":["solid-transform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,0CAA0C;AAC1C,OAAO,EAAE,MAAM,0BAA0B,CAAA;AACzC,0CAA0C;AAC1C,OAAO,cAAc,MAAM,8BAA8B,CAAA;AACzD,0CAA0C;AAC1C,OAAO,KAAK,MAAM,oBAAoB,CAAA;AAUtC,MAAM,kBAAkB,GAAG,wBAAwB,CAAA;AACnD,MAAM,SAAS,GAAG,cAAc,CAAA;AAChC,MAAM,UAAU,GAAG,gBAAgB,CAAA;AAEnC,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IACnC,MAAM,GAAG,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAC3F,OAAO,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AACtD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACtC,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,SAAiB;IAC7D,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,UAAU;YACb,OAAO,wBAAwB,CAAA;QACjC,KAAK,gBAAgB;YACnB,OAAO,8BAA8B,CAAA;QACvC;YACE,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAY,EAAE,OAAoC;IAC3F,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW;QACjC,CAAC,CAAC;YACE;gBACE,cAAc;gBACd;oBACE,WAAW,CAAC,SAAiB;wBAC3B,OAAO,OAAO,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,IAAI,SAAS,CAAA;oBACtD,CAAC;iBACF;aACF;SACF;QACH,CAAC,CAAC,EAAE,CAAA;IAEN,MAAM,OAAO,GAAG,EAAE,CAAA;IAElB,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,IAAI,CAAC;YACX,KAAK;YACL;gBACE,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,gBAAgB;gBAClD,QAAQ,EAAE,WAAW;aACtB;SACF,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACpB,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE;QAC7C,QAAQ;QACR,UAAU,EAAE,KAAK;QACjB,OAAO,EAAE,KAAK;QACd,OAAO;QACP,OAAO;KACR,CAAC,CAAA;IAEF,OAAO,WAAW,EAAE,IAAI,IAAI,IAAI,CAAA;AAClC,CAAC"} |
| import { after, afterEach, before, beforeEach, describe, test } from "node:test"; | ||
| export { after as afterAll, afterEach, before as beforeAll, beforeEach, describe, test }; | ||
| export declare const it: typeof test; | ||
| export declare function expect(received: unknown): { | ||
| readonly not: /*elided*/ any; | ||
| toBe(expected: unknown): void; | ||
| toBeDefined(): void; | ||
| toBeFalsy(): void; | ||
| toBeTruthy(): void; | ||
| toContain(expected: unknown): void; | ||
| toEqual(expected: unknown): void; | ||
| }; |
+106
-4
@@ -1,6 +0,106 @@ | ||
| // @bun | ||
| // src/elements/catalogue.ts | ||
| import { | ||
| extend, | ||
| getComponentCatalogue | ||
| } from "./chunk-7fkmdv3h.js"; | ||
| ASCIIFontRenderable, | ||
| BoxRenderable, | ||
| CodeRenderable, | ||
| DiffRenderable, | ||
| InputRenderable, | ||
| LineNumberRenderable, | ||
| MarkdownRenderable, | ||
| ScrollBoxRenderable, | ||
| SelectRenderable, | ||
| TabSelectRenderable, | ||
| TextareaRenderable, | ||
| TextAttributes, | ||
| TextNodeRenderable, | ||
| TextRenderable | ||
| } from "@opentui/core"; | ||
| class SpanRenderable extends TextNodeRenderable { | ||
| _ctx; | ||
| constructor(_ctx, options) { | ||
| super(options); | ||
| this._ctx = _ctx; | ||
| } | ||
| } | ||
| class TextModifierRenderable extends SpanRenderable { | ||
| constructor(options, modifier) { | ||
| super(null, options); | ||
| if (modifier === "b" || modifier === "strong") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.BOLD; | ||
| } else if (modifier === "i" || modifier === "em") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.ITALIC; | ||
| } else if (modifier === "u") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.UNDERLINE; | ||
| } | ||
| } | ||
| } | ||
| class BoldSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "b"); | ||
| } | ||
| } | ||
| class ItalicSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "i"); | ||
| } | ||
| } | ||
| class UnderlineSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "u"); | ||
| } | ||
| } | ||
| class LineBreakRenderable extends SpanRenderable { | ||
| constructor(_ctx, options) { | ||
| super(null, options); | ||
| this.add(); | ||
| } | ||
| add() { | ||
| return super.add(` | ||
| `); | ||
| } | ||
| } | ||
| class LinkRenderable extends SpanRenderable { | ||
| constructor(_ctx, options) { | ||
| const linkOptions = { | ||
| ...options, | ||
| link: { url: options.href } | ||
| }; | ||
| super(null, linkOptions); | ||
| } | ||
| } | ||
| var baseComponents = { | ||
| box: BoxRenderable, | ||
| text: TextRenderable, | ||
| input: InputRenderable, | ||
| select: SelectRenderable, | ||
| textarea: TextareaRenderable, | ||
| ascii_font: ASCIIFontRenderable, | ||
| tab_select: TabSelectRenderable, | ||
| scrollbox: ScrollBoxRenderable, | ||
| code: CodeRenderable, | ||
| diff: DiffRenderable, | ||
| line_number: LineNumberRenderable, | ||
| markdown: MarkdownRenderable, | ||
| span: SpanRenderable, | ||
| strong: BoldSpanRenderable, | ||
| b: BoldSpanRenderable, | ||
| em: ItalicSpanRenderable, | ||
| i: ItalicSpanRenderable, | ||
| u: UnderlineSpanRenderable, | ||
| br: LineBreakRenderable, | ||
| a: LinkRenderable | ||
| }; | ||
| var componentCatalogue = { ...baseComponents }; | ||
| function extend(objects) { | ||
| Object.assign(componentCatalogue, objects); | ||
| } | ||
| function getComponentCatalogue() { | ||
| return componentCatalogue; | ||
| } | ||
| export { | ||
@@ -10,1 +110,3 @@ getComponentCatalogue, | ||
| }; | ||
| //# debugId=4D3EF7806518248664756E2164756E21 |
+1
-1
| import { CliRenderer, type CliRendererConfig } from "@opentui/core"; | ||
| import { type TestRendererOptions } from "@opentui/core/testing"; | ||
| import type { JSX } from "./jsx-runtime"; | ||
| import type { JSX } from "./jsx-runtime.js"; | ||
| export declare const render: (node: () => JSX.Element, rendererOrConfig?: CliRenderer | CliRendererConfig) => Promise<void>; | ||
@@ -5,0 +5,0 @@ export declare const testRender: (node: () => JSX.Element, renderConfig?: TestRendererOptions) => Promise<import("@opentui/core/testing").TestRendererSetup>; |
+146
-72
@@ -1,24 +0,103 @@ | ||
| // @bun | ||
| import { | ||
| BoldSpanRenderable, | ||
| ItalicSpanRenderable, | ||
| LineBreakRenderable, | ||
| LinkRenderable, | ||
| UnderlineSpanRenderable, | ||
| baseComponents, | ||
| componentCatalogue, | ||
| extend, | ||
| getComponentCatalogue, | ||
| textNodeKeys | ||
| } from "./chunk-7fkmdv3h.js"; | ||
| // index.ts | ||
| import { CliRenderer, createCliRenderer, engine as engine2 } from "@opentui/core"; | ||
| import { createTestRenderer } from "@opentui/core/testing"; | ||
| // src/elements/catalogue.ts | ||
| import { ASCIIFontRenderable, BoxRenderable, CodeRenderable, DiffRenderable, InputRenderable, LineNumberRenderable, MarkdownRenderable, ScrollBoxRenderable, SelectRenderable, TabSelectRenderable, TextareaRenderable, TextAttributes, TextNodeRenderable, TextRenderable } from "@opentui/core"; | ||
| class SpanRenderable extends TextNodeRenderable { | ||
| constructor(_ctx, options) { | ||
| super(options); | ||
| this._ctx = _ctx; | ||
| } | ||
| } | ||
| var textNodeKeys = ["span", "b", "strong", "i", "em", "u", "a"]; | ||
| class TextModifierRenderable extends SpanRenderable { | ||
| constructor(options, modifier) { | ||
| super(null, options); | ||
| if (modifier === "b" || modifier === "strong") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.BOLD; | ||
| } else if (modifier === "i" || modifier === "em") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.ITALIC; | ||
| } else if (modifier === "u") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.UNDERLINE; | ||
| } | ||
| } | ||
| } | ||
| class BoldSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "b"); | ||
| } | ||
| } | ||
| class ItalicSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "i"); | ||
| } | ||
| } | ||
| class UnderlineSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "u"); | ||
| } | ||
| } | ||
| class LineBreakRenderable extends SpanRenderable { | ||
| constructor(_ctx, options) { | ||
| super(null, options); | ||
| this.add(); | ||
| } | ||
| add() { | ||
| return super.add(` | ||
| `); | ||
| } | ||
| } | ||
| class LinkRenderable extends SpanRenderable { | ||
| constructor(_ctx, options) { | ||
| const linkOptions = { | ||
| ...options, | ||
| link: { | ||
| url: options.href | ||
| } | ||
| }; | ||
| super(null, linkOptions); | ||
| } | ||
| } | ||
| var baseComponents = { | ||
| box: BoxRenderable, | ||
| text: TextRenderable, | ||
| input: InputRenderable, | ||
| select: SelectRenderable, | ||
| textarea: TextareaRenderable, | ||
| ascii_font: ASCIIFontRenderable, | ||
| tab_select: TabSelectRenderable, | ||
| scrollbox: ScrollBoxRenderable, | ||
| code: CodeRenderable, | ||
| diff: DiffRenderable, | ||
| line_number: LineNumberRenderable, | ||
| markdown: MarkdownRenderable, | ||
| span: SpanRenderable, | ||
| strong: BoldSpanRenderable, | ||
| b: BoldSpanRenderable, | ||
| em: ItalicSpanRenderable, | ||
| i: ItalicSpanRenderable, | ||
| u: UnderlineSpanRenderable, | ||
| br: LineBreakRenderable, | ||
| a: LinkRenderable | ||
| }; | ||
| var componentCatalogue = { | ||
| ...baseComponents | ||
| }; | ||
| function extend(objects) { | ||
| Object.assign(componentCatalogue, objects); | ||
| } | ||
| function getComponentCatalogue() { | ||
| return componentCatalogue; | ||
| } | ||
| // src/elements/hooks.ts | ||
| import { | ||
| engine, | ||
| Timeline | ||
| } from "@opentui/core"; | ||
| import { createContext, createSignal, onCleanup, onMount, useContext } from "solid-js"; | ||
| import { engine, Timeline } from "@opentui/core"; | ||
| import { createContext, createSignal, onCleanup, onMount, useContext } from "solid-js/dist/solid.js"; | ||
| var RendererContext = createContext(); | ||
@@ -43,5 +122,11 @@ var useRenderer = () => { | ||
| const renderer = useRenderer(); | ||
| const [terminalDimensions, setTerminalDimensions] = createSignal({ width: renderer.width, height: renderer.height }); | ||
| const [terminalDimensions, setTerminalDimensions] = createSignal({ | ||
| width: renderer.width, | ||
| height: renderer.height | ||
| }); | ||
| const callback = (width, height) => { | ||
| setTerminalDimensions({ width, height }); | ||
| setTerminalDimensions({ | ||
| width, | ||
| height | ||
| }); | ||
| }; | ||
@@ -120,27 +205,11 @@ onResize(callback); | ||
| // src/elements/extras.ts | ||
| import { createEffect, createMemo as createMemo2, getOwner, onCleanup as onCleanup2, runWithOwner, splitProps, untrack as untrack2 } from "solid-js"; | ||
| import { createEffect, createMemo as createMemo2, getOwner, onCleanup as onCleanup2, runWithOwner, splitProps, untrack as untrack2 } from "solid-js/dist/solid.js"; | ||
| // src/reconciler.ts | ||
| import { | ||
| BaseRenderable, | ||
| createTextAttributes, | ||
| InputRenderable, | ||
| InputRenderableEvents, | ||
| isTextNodeRenderable, | ||
| parseColor, | ||
| Renderable, | ||
| RootTextNodeRenderable, | ||
| ScrollBoxRenderable, | ||
| SelectRenderable, | ||
| SelectRenderableEvents, | ||
| TabSelectRenderable, | ||
| TabSelectRenderableEvents, | ||
| TextNodeRenderable, | ||
| TextRenderable | ||
| } from "@opentui/core"; | ||
| import { BaseRenderable, createTextAttributes, InputRenderable as InputRenderable2, InputRenderableEvents, isTextNodeRenderable, parseColor, Renderable, RootTextNodeRenderable, ScrollBoxRenderable as ScrollBoxRenderable2, SelectRenderable as SelectRenderable2, SelectRenderableEvents, TabSelectRenderable as TabSelectRenderable2, TabSelectRenderableEvents, TextNodeRenderable as TextNodeRenderable2, TextRenderable as TextRenderable2 } from "@opentui/core"; | ||
| import { decodeHTML } from "entities"; | ||
| import { useContext as useContext2 } from "solid-js"; | ||
| import { useContext as useContext2 } from "solid-js/dist/solid.js"; | ||
| // src/renderer/universal.js | ||
| import { createRoot, createRenderEffect, createMemo, createComponent, untrack, mergeProps } from "solid-js"; | ||
| import { createRoot, createRenderEffect, createMemo, createComponent, untrack, mergeProps } from "solid-js/dist/solid.js"; | ||
| var memo = (fn) => createMemo(() => fn()); | ||
@@ -404,3 +473,3 @@ function createRenderer({ | ||
| // src/renderer/index.ts | ||
| import { mergeProps as mergeProps2 } from "solid-js"; | ||
| import { mergeProps as mergeProps2 } from "solid-js/dist/solid.js"; | ||
| function createRenderer2(options) { | ||
@@ -431,3 +500,3 @@ const renderer = createRenderer(options); | ||
| // src/reconciler.ts | ||
| class TextNode extends TextNodeRenderable { | ||
| class TextNode extends TextNodeRenderable2 { | ||
| static fromString(text, options = {}) { | ||
@@ -446,3 +515,3 @@ const node = new TextNode(options); | ||
| let children; | ||
| if (node instanceof TextRenderable) { | ||
| if (node instanceof TextRenderable2) { | ||
| children = node.getTextChildren(); | ||
@@ -464,3 +533,3 @@ } else { | ||
| if (isTextNodeRenderable(node)) { | ||
| if (!(parent instanceof TextRenderable) && !isTextNodeRenderable(parent)) { | ||
| if (!(parent instanceof TextRenderable2) && !isTextNodeRenderable(parent)) { | ||
| throw new Error(`Orphan text error: "${node.toChunks().map((c) => c.text).join("")}" must have a <text> as a parent: ${parent.id} above ${node.id}`); | ||
@@ -513,3 +582,5 @@ } | ||
| } | ||
| return TextNode.fromString(decodeHTML(value), { id }); | ||
| return TextNode.fromString(decodeHTML(value), { | ||
| id | ||
| }); | ||
| } | ||
@@ -528,3 +599,3 @@ function createSlotNode() { | ||
| const scrollBoxCandidate = parent?.parent?.parent?.parent; | ||
| if (scrollBoxCandidate instanceof ScrollBoxRenderable && scrollBoxCandidate.content === parent) { | ||
| if (scrollBoxCandidate instanceof ScrollBoxRenderable2 && scrollBoxCandidate.content === parent) { | ||
| parent = scrollBoxCandidate; | ||
@@ -559,3 +630,5 @@ } | ||
| } | ||
| const element = new elements[tagName](solidRenderer, { id }); | ||
| const element = new elements[tagName](solidRenderer, { | ||
| id | ||
| }); | ||
| log("Element created with id:", id); | ||
@@ -585,3 +658,5 @@ return element; | ||
| if (name === "href") { | ||
| node.link = { url: value }; | ||
| node.link = { | ||
| url: value | ||
| }; | ||
| return; | ||
@@ -613,7 +688,7 @@ } | ||
| let event = undefined; | ||
| if (node instanceof SelectRenderable) { | ||
| if (node instanceof SelectRenderable2) { | ||
| event = SelectRenderableEvents.SELECTION_CHANGED; | ||
| } else if (node instanceof TabSelectRenderable) { | ||
| } else if (node instanceof TabSelectRenderable2) { | ||
| event = TabSelectRenderableEvents.SELECTION_CHANGED; | ||
| } else if (node instanceof InputRenderable) { | ||
| } else if (node instanceof InputRenderable2) { | ||
| event = InputRenderableEvents.CHANGE; | ||
@@ -631,3 +706,3 @@ } | ||
| case "onInput": | ||
| if (node instanceof InputRenderable) { | ||
| if (node instanceof InputRenderable2) { | ||
| if (value) { | ||
@@ -642,3 +717,3 @@ node.on(InputRenderableEvents.INPUT, value); | ||
| case "onSubmit": | ||
| if (node instanceof InputRenderable) { | ||
| if (node instanceof InputRenderable2) { | ||
| if (value) { | ||
@@ -655,3 +730,3 @@ node.on(InputRenderableEvents.ENTER, value); | ||
| case "onSelect": | ||
| if (node instanceof SelectRenderable) { | ||
| if (node instanceof SelectRenderable2) { | ||
| if (value) { | ||
@@ -663,3 +738,3 @@ node.on(SelectRenderableEvents.ITEM_SELECTED, value); | ||
| } | ||
| } else if (node instanceof TabSelectRenderable) { | ||
| } else if (node instanceof TabSelectRenderable2) { | ||
| if (value) { | ||
@@ -755,3 +830,5 @@ node.on(TabSelectRenderableEvents.ITEM_SELECTED, value); | ||
| onCleanup2(() => el.remove(container.id)); | ||
| }, undefined, { render: true }); | ||
| }, undefined, { | ||
| render: true | ||
| }); | ||
| return marker; | ||
@@ -780,3 +857,3 @@ } | ||
| // src/elements/slot.ts | ||
| import { BaseRenderable as BaseRenderable2, isTextNodeRenderable as isTextNodeRenderable2, TextNodeRenderable as TextNodeRenderable2, TextRenderable as TextRenderable2, Yoga } from "@opentui/core"; | ||
| import { BaseRenderable as BaseRenderable2, isTextNodeRenderable as isTextNodeRenderable2, TextNodeRenderable as TextNodeRenderable3, TextRenderable as TextRenderable3, Yoga } from "@opentui/core"; | ||
| function getLayoutNodeConstructor(parent) { | ||
@@ -818,7 +895,8 @@ const parentLayoutNode = parent?.getLayoutNode?.(); | ||
| class TextSlotRenderable extends TextNodeRenderable2 { | ||
| slotParent; | ||
| class TextSlotRenderable extends TextNodeRenderable3 { | ||
| destroyed = false; | ||
| constructor(id, parent) { | ||
| super({ id }); | ||
| super({ | ||
| id | ||
| }); | ||
| this._visible = false; | ||
@@ -850,6 +928,3 @@ this.slotParent = parent; | ||
| class LayoutSlotRenderable extends SlotBaseRenderable { | ||
| yogaNode; | ||
| slotParent; | ||
| destroyed = false; | ||
| yogaNodeConstructor; | ||
| yogaNodeFreed = false; | ||
@@ -922,3 +997,3 @@ constructor(id, parent, layoutParent) { | ||
| isTextSlotParent(parent) { | ||
| return isTextNodeRenderable2(parent) || parent instanceof TextRenderable2; | ||
| return isTextNodeRenderable2(parent) || parent instanceof TextRenderable3; | ||
| } | ||
@@ -1085,7 +1160,4 @@ getCurrentSlotChild(nodesByParent) { | ||
| // src/scrollback.ts | ||
| import { | ||
| BoxRenderable, | ||
| RootRenderable | ||
| } from "@opentui/core"; | ||
| import { createSignal as createSignal2 } from "solid-js"; | ||
| import { BoxRenderable as BoxRenderable2, RootRenderable } from "@opentui/core"; | ||
| import { createSignal as createSignal2 } from "solid-js/dist/solid.js"; | ||
| var solidScrollbackRootCounter = 0; | ||
@@ -1184,3 +1256,3 @@ var MAX_AUTO_HEIGHT_PASSES = 4; | ||
| const firstLineOffset = width - firstLineWidth; | ||
| const root = new BoxRenderable(ctx.renderContext, { | ||
| const root = new BoxRenderable2(ctx.renderContext, { | ||
| id: `solid-scrollback-root-${solidScrollbackRootCounter++}`, | ||
@@ -1249,3 +1321,3 @@ position: "absolute", | ||
| import { createSlotRegistry } from "@opentui/core"; | ||
| import { children, createMemo as createMemo3, createSignal as createSignal3, ErrorBoundary, For, onCleanup as onCleanup3, splitProps as splitProps2 } from "solid-js"; | ||
| import { children, createMemo as createMemo3, createSignal as createSignal3, ErrorBoundary, For, onCleanup as onCleanup3, splitProps as splitProps2 } from "solid-js/dist/solid.js"; | ||
| var EMPTY_ENTRY_IDS = []; | ||
@@ -1536,1 +1608,3 @@ function createSolidSlotRegistry(renderer, context, options = {}) { | ||
| }; | ||
| //# debugId=11EF7868D3A4CD2A64756E2164756E21 |
+9
-6
@@ -1,2 +0,1 @@ | ||
| import { Renderable } from "@opentui/core" | ||
| import type { | ||
@@ -18,10 +17,14 @@ AsciiFontProps, | ||
| } from "./src/types/elements.js" | ||
| import type { DomNode } from "./dist" | ||
| import type { JSX as SolidJSX } from "solid-js" | ||
| declare namespace JSX { | ||
| // Replace Node with Renderable | ||
| type Element = DomNode | ArrayElement | string | number | boolean | null | undefined | ||
| type JsxComponent = (props: Record<string, unknown>) => unknown | ||
| type ArrayElement = Array<Element> | ||
| export declare function jsx(type: string | JsxComponent, props?: Record<string, unknown> | null): JSX.Element | ||
| export declare const jsxs: typeof jsx | ||
| export declare function jsxDEV(type: string | JsxComponent, props?: Record<string, unknown> | null): JSX.Element | ||
| export declare function Fragment(props: { children?: JSX.Element }): JSX.Element | ||
| export declare namespace JSX { | ||
| type Element = SolidJSX.Element | ||
| interface IntrinsicElements extends ExtendedIntrinsicElements<OpenTUIComponents> { | ||
@@ -28,0 +31,0 @@ box: BoxProps |
+27
-9
@@ -7,3 +7,3 @@ { | ||
| "type": "module", | ||
| "version": "0.3.4", | ||
| "version": "0.4.0", | ||
| "description": "SolidJS renderer for OpenTUI", | ||
@@ -19,19 +19,29 @@ "license": "MIT", | ||
| "types": "./index.d.ts", | ||
| "bun": "./index.bun.js", | ||
| "node": "./index.js", | ||
| "import": "./index.js", | ||
| "require": "./index.js" | ||
| "default": "./index.js" | ||
| }, | ||
| "./preload": { | ||
| "import": "./scripts/preload.ts" | ||
| "bun": "./scripts/preload.js", | ||
| "node": "./scripts/preload.node.js", | ||
| "default": "./scripts/preload.node.js" | ||
| }, | ||
| "./bun-plugin": { | ||
| "types": "./scripts/solid-plugin.d.ts", | ||
| "import": "./scripts/solid-plugin.ts" | ||
| "bun": "./scripts/solid-plugin.js", | ||
| "node": "./scripts/solid-plugin.node.js", | ||
| "default": "./scripts/solid-plugin.node.js" | ||
| }, | ||
| "./runtime-plugin-support": { | ||
| "types": "./scripts/runtime-plugin-support.d.ts", | ||
| "import": "./scripts/runtime-plugin-support.ts" | ||
| "bun": "./scripts/runtime-plugin-support.js", | ||
| "node": "./scripts/runtime-plugin-support.node.js", | ||
| "default": "./scripts/runtime-plugin-support.node.js" | ||
| }, | ||
| "./runtime-plugin-support/configure": { | ||
| "types": "./scripts/runtime-plugin-support-configure.d.ts", | ||
| "import": "./scripts/runtime-plugin-support-configure.ts" | ||
| "bun": "./scripts/runtime-plugin-support-configure.js", | ||
| "node": "./scripts/runtime-plugin-support-configure.node.js", | ||
| "default": "./scripts/runtime-plugin-support-configure.node.js" | ||
| }, | ||
@@ -43,4 +53,12 @@ "./components": { | ||
| }, | ||
| "./jsx-runtime": "./jsx-runtime.d.ts", | ||
| "./jsx-dev-runtime": "./jsx-runtime.d.ts" | ||
| "./jsx-runtime": { | ||
| "types": "./jsx-runtime.d.ts", | ||
| "import": "./jsx-runtime.js", | ||
| "default": "./jsx-runtime.js" | ||
| }, | ||
| "./jsx-dev-runtime": { | ||
| "types": "./jsx-dev-runtime.d.ts", | ||
| "import": "./jsx-dev-runtime.js", | ||
| "default": "./jsx-dev-runtime.js" | ||
| } | ||
| }, | ||
@@ -50,3 +68,3 @@ "dependencies": { | ||
| "@babel/preset-typescript": "7.27.1", | ||
| "@opentui/core": "0.3.4", | ||
| "@opentui/core": "0.4.0", | ||
| "babel-plugin-module-resolver": "5.0.2", | ||
@@ -53,0 +71,0 @@ "babel-preset-solid": "1.9.12", |
| import { type BunPlugin } from "bun"; | ||
| export type ResolveImportPath = (specifier: string) => string | null; | ||
| import { type ResolveImportPath } from "./solid-transform.js"; | ||
| export interface CreateSolidTransformPluginOptions { | ||
@@ -4,0 +4,0 @@ moduleName?: string; |
| import { type DomNode } from "../reconciler.js"; | ||
| import type { JSX } from "../../jsx-runtime"; | ||
| import type { JSX } from "../../jsx-runtime.js"; | ||
| import type { ValidComponent, ComponentProps } from "solid-js"; | ||
@@ -15,3 +15,3 @@ /** | ||
| children: JSX.Element; | ||
| }): DomNode; | ||
| }): JSX.Element; | ||
| export type DynamicProps<T extends ValidComponent, P = ComponentProps<T>> = { | ||
@@ -18,0 +18,0 @@ [K in keyof P]: P[K]; |
| import type { ASCIIFontOptions, ASCIIFontRenderable, BaseRenderable, BoxOptions, BoxRenderable, CodeOptions, CodeRenderable, InputRenderable, InputRenderableOptions, KeyEvent, MarkdownOptions, MarkdownRenderable, RenderableOptions, RenderContext, ScrollBoxOptions, ScrollBoxRenderable, SelectOption, SelectRenderable, SelectRenderableOptions, TabSelectOption, TabSelectRenderable, TabSelectRenderableOptions, TextareaOptions, TextareaRenderable, TextNodeRenderable, TextOptions, TextRenderable } from "@opentui/core"; | ||
| import type { Ref } from "solid-js"; | ||
| import type { JSX } from "../../jsx-runtime"; | ||
| import type { JSX } from "../../jsx-runtime.js"; | ||
| /** Properties that should not be included in the style prop */ | ||
@@ -5,0 +5,0 @@ export type NonStyledProps = "id" | "buffered" | "live" | "enableLayout" | "selectable" | "renderAfter" | "renderBefore" | `on${string}`; |
| // @bun | ||
| // src/elements/catalogue.ts | ||
| import { | ||
| ASCIIFontRenderable, | ||
| BoxRenderable, | ||
| CodeRenderable, | ||
| DiffRenderable, | ||
| InputRenderable, | ||
| LineNumberRenderable, | ||
| MarkdownRenderable, | ||
| ScrollBoxRenderable, | ||
| SelectRenderable, | ||
| TabSelectRenderable, | ||
| TextareaRenderable, | ||
| TextAttributes, | ||
| TextNodeRenderable, | ||
| TextRenderable | ||
| } from "@opentui/core"; | ||
| class SpanRenderable extends TextNodeRenderable { | ||
| _ctx; | ||
| constructor(_ctx, options) { | ||
| super(options); | ||
| this._ctx = _ctx; | ||
| } | ||
| } | ||
| var textNodeKeys = ["span", "b", "strong", "i", "em", "u", "a"]; | ||
| class TextModifierRenderable extends SpanRenderable { | ||
| constructor(options, modifier) { | ||
| super(null, options); | ||
| if (modifier === "b" || modifier === "strong") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.BOLD; | ||
| } else if (modifier === "i" || modifier === "em") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.ITALIC; | ||
| } else if (modifier === "u") { | ||
| this.attributes = (this.attributes || 0) | TextAttributes.UNDERLINE; | ||
| } | ||
| } | ||
| } | ||
| class BoldSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "b"); | ||
| } | ||
| } | ||
| class ItalicSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "i"); | ||
| } | ||
| } | ||
| class UnderlineSpanRenderable extends TextModifierRenderable { | ||
| constructor(options) { | ||
| super(options, "u"); | ||
| } | ||
| } | ||
| class LineBreakRenderable extends SpanRenderable { | ||
| constructor(_ctx, options) { | ||
| super(null, options); | ||
| this.add(); | ||
| } | ||
| add() { | ||
| return super.add(` | ||
| `); | ||
| } | ||
| } | ||
| class LinkRenderable extends SpanRenderable { | ||
| constructor(_ctx, options) { | ||
| const linkOptions = { | ||
| ...options, | ||
| link: { url: options.href } | ||
| }; | ||
| super(null, linkOptions); | ||
| } | ||
| } | ||
| var baseComponents = { | ||
| box: BoxRenderable, | ||
| text: TextRenderable, | ||
| input: InputRenderable, | ||
| select: SelectRenderable, | ||
| textarea: TextareaRenderable, | ||
| ascii_font: ASCIIFontRenderable, | ||
| tab_select: TabSelectRenderable, | ||
| scrollbox: ScrollBoxRenderable, | ||
| code: CodeRenderable, | ||
| diff: DiffRenderable, | ||
| line_number: LineNumberRenderable, | ||
| markdown: MarkdownRenderable, | ||
| span: SpanRenderable, | ||
| strong: BoldSpanRenderable, | ||
| b: BoldSpanRenderable, | ||
| em: ItalicSpanRenderable, | ||
| i: ItalicSpanRenderable, | ||
| u: UnderlineSpanRenderable, | ||
| br: LineBreakRenderable, | ||
| a: LinkRenderable | ||
| }; | ||
| var componentCatalogue = { ...baseComponents }; | ||
| function extend(objects) { | ||
| Object.assign(componentCatalogue, objects); | ||
| } | ||
| function getComponentCatalogue() { | ||
| return componentCatalogue; | ||
| } | ||
| export { textNodeKeys, BoldSpanRenderable, ItalicSpanRenderable, UnderlineSpanRenderable, LineBreakRenderable, LinkRenderable, baseComponents, componentCatalogue, extend, getComponentCatalogue }; |
| export var textNodeKeys: string[]; | ||
| export class BoldSpanRenderable extends TextModifierRenderable { | ||
| constructor(options: any); | ||
| } | ||
| export class ItalicSpanRenderable extends TextModifierRenderable { | ||
| constructor(options: any); | ||
| } | ||
| export class UnderlineSpanRenderable extends TextModifierRenderable { | ||
| constructor(options: any); | ||
| } | ||
| export class LineBreakRenderable extends SpanRenderable { | ||
| add(): number; | ||
| } | ||
| export class LinkRenderable extends SpanRenderable { | ||
| } | ||
| export namespace baseComponents { | ||
| export { BoxRenderable as box }; | ||
| export { TextRenderable as text }; | ||
| export { InputRenderable as input }; | ||
| export { SelectRenderable as select }; | ||
| export { TextareaRenderable as textarea }; | ||
| export { ASCIIFontRenderable as ascii_font }; | ||
| export { TabSelectRenderable as tab_select }; | ||
| export { ScrollBoxRenderable as scrollbox }; | ||
| export { CodeRenderable as code }; | ||
| export { DiffRenderable as diff }; | ||
| export { LineNumberRenderable as line_number }; | ||
| export { MarkdownRenderable as markdown }; | ||
| export { SpanRenderable as span }; | ||
| export { BoldSpanRenderable as strong }; | ||
| export { BoldSpanRenderable as b }; | ||
| export { ItalicSpanRenderable as em }; | ||
| export { ItalicSpanRenderable as i }; | ||
| export { UnderlineSpanRenderable as u }; | ||
| export { LineBreakRenderable as br }; | ||
| export { LinkRenderable as a }; | ||
| } | ||
| export namespace componentCatalogue { } | ||
| export function extend(objects: any): void; | ||
| export function getComponentCatalogue(): { | ||
| box: typeof BoxRenderable; | ||
| text: typeof TextRenderable; | ||
| input: typeof InputRenderable; | ||
| select: typeof SelectRenderable; | ||
| textarea: typeof TextareaRenderable; | ||
| ascii_font: typeof ASCIIFontRenderable; | ||
| tab_select: typeof TabSelectRenderable; | ||
| scrollbox: typeof ScrollBoxRenderable; | ||
| code: typeof CodeRenderable; | ||
| diff: typeof DiffRenderable; | ||
| line_number: typeof LineNumberRenderable; | ||
| markdown: typeof MarkdownRenderable; | ||
| span: typeof SpanRenderable; | ||
| strong: typeof BoldSpanRenderable; | ||
| b: typeof BoldSpanRenderable; | ||
| em: typeof ItalicSpanRenderable; | ||
| i: typeof ItalicSpanRenderable; | ||
| u: typeof UnderlineSpanRenderable; | ||
| br: typeof LineBreakRenderable; | ||
| a: typeof LinkRenderable; | ||
| }; | ||
| declare class TextModifierRenderable extends SpanRenderable { | ||
| } | ||
| declare class SpanRenderable extends TextNodeRenderable { | ||
| constructor(_ctx: any, options: any); | ||
| _ctx: any; | ||
| } | ||
| import { BoxRenderable } from "@opentui/core"; | ||
| import { TextRenderable } from "@opentui/core"; | ||
| import { InputRenderable } from "@opentui/core"; | ||
| import { SelectRenderable } from "@opentui/core"; | ||
| import { TextareaRenderable } from "@opentui/core"; | ||
| import { ASCIIFontRenderable } from "@opentui/core"; | ||
| import { TabSelectRenderable } from "@opentui/core"; | ||
| import { ScrollBoxRenderable } from "@opentui/core"; | ||
| import { CodeRenderable } from "@opentui/core"; | ||
| import { DiffRenderable } from "@opentui/core"; | ||
| import { LineNumberRenderable } from "@opentui/core"; | ||
| import { MarkdownRenderable } from "@opentui/core"; | ||
| import { TextNodeRenderable } from "@opentui/core"; | ||
| export {}; |
-118
| export function writeSolidToScrollback(renderer: any, node: any, options?: {}): void; | ||
| export function useTimeline(options?: {}): Timeline; | ||
| export function useTerminalDimensions(): import("solid-js").Accessor<{ | ||
| width: any; | ||
| height: any; | ||
| }>; | ||
| export function useSelectionHandler(callback: any): void; | ||
| export function useRenderer(): any; | ||
| export function usePaste(callback: any): void; | ||
| export function useKeyboard(callback: any, options: any): void; | ||
| export function useKeyHandler(callback: any, options: any): void; | ||
| export function use(fn: any, element: any, arg: any): any; | ||
| import { textNodeKeys } from "./chunk-7fkmdv3h.js"; | ||
| export function testRender(node: any, renderConfig?: {}): Promise<import("@opentui/core/testing").TestRendererSetup>; | ||
| export function spread(node: any, accessor: any, skipChildren: any): void; | ||
| export function setProp(node: any, name: any, value: any, prev: any): any; | ||
| export function render(node: any, rendererOrConfig?: {}): Promise<void>; | ||
| export function onResize(callback: any): void; | ||
| export function onFocus(callback: any): void; | ||
| export function onBlur(callback: any): void; | ||
| declare var mergeProps3: typeof mergeProps; | ||
| declare function memo2(fn: any): import("solid-js").Accessor<any>; | ||
| export var insertNode: any; | ||
| export function insert(parent: any, accessor: any, marker: any, initial: any): any; | ||
| import { getComponentCatalogue } from "./chunk-7fkmdv3h.js"; | ||
| import { extend } from "./chunk-7fkmdv3h.js"; | ||
| export var effect: typeof createRenderEffect; | ||
| export var createTextNode: any; | ||
| export function createSolidSlotRegistry(renderer: any, context: any, options?: {}): import("@opentui/core").SlotRegistry<any, object, any>; | ||
| export function createSlotNode(): SlotRenderable; | ||
| export function createSlot(registry: any, options?: {}): (props: any) => any; | ||
| export function createScrollbackWriter(node: any, options?: {}): (ctx: any) => { | ||
| root: BoxRenderable; | ||
| width: number; | ||
| height: number; | ||
| rowColumns: any; | ||
| startOnNewLine: any; | ||
| trailingNewline: any; | ||
| teardown: () => void; | ||
| }; | ||
| export var createElement: any; | ||
| export function createDynamic(component: any, props: any): import("solid-js").Accessor<any>; | ||
| declare var createComponent2: typeof createComponent; | ||
| import { componentCatalogue } from "./chunk-7fkmdv3h.js"; | ||
| import { baseComponents } from "./chunk-7fkmdv3h.js"; | ||
| export function _render(code: any, element: any): undefined; | ||
| import { UnderlineSpanRenderable } from "./chunk-7fkmdv3h.js"; | ||
| export function TimeToFirstDraw(props: any): any; | ||
| export class TextSlotRenderable extends TextNodeRenderable { | ||
| constructor(id: any, parent: any); | ||
| slotParent: any; | ||
| destroyed: boolean; | ||
| detachFromSlot(): void; | ||
| disposeWithoutSlotCascade(): void; | ||
| } | ||
| export class SlotRenderable extends SlotBaseRenderable { | ||
| destroyed: boolean; | ||
| layoutNodesByParent: Map<any, any>; | ||
| textNodesByParent: Map<any, any>; | ||
| layoutNodeCount: number; | ||
| textNodeCount: number; | ||
| get layoutNode(): any; | ||
| get textNode(): any; | ||
| isTextSlotParent(parent: any): parent is TextRenderable | TextNodeRenderable; | ||
| getCurrentSlotChild(nodesByParent: any): any; | ||
| getTextNodeForParent(parent: any): any; | ||
| getLayoutNodeForParent(parent: any): any; | ||
| takeReusableTextNode(parent: any): any; | ||
| takeReusableLayoutNode(parent: any): any; | ||
| disposeDetachedTextNodes(): void; | ||
| disposeDetachedIncompatibleLayoutNodes(parent: any): void; | ||
| getAttachedSlotParent(excludedNode: any): any; | ||
| hasOtherAttachedSlotChildren(excludedNode: any): boolean; | ||
| getSlotChild(parent: any): any; | ||
| getSlotChildForRemoval(parent: any): any; | ||
| didRemoveSlotChild(parent: any, child: any): void; | ||
| } | ||
| export function Slot(props: any): import("solid-js").Accessor<any>; | ||
| export var RendererContext: import("solid-js").Context<any>; | ||
| export function Portal(props: any): SlotRenderable; | ||
| import { LinkRenderable } from "./chunk-7fkmdv3h.js"; | ||
| import { LineBreakRenderable } from "./chunk-7fkmdv3h.js"; | ||
| export class LayoutSlotRenderable extends SlotBaseRenderable { | ||
| constructor(id: any, parent: any, layoutParent: any); | ||
| yogaNode: any; | ||
| slotParent: any; | ||
| destroyed: boolean; | ||
| yogaNodeConstructor: any; | ||
| yogaNodeFreed: boolean; | ||
| getLayoutNode(): any; | ||
| updateFromLayout(): void; | ||
| updateLayout(): void; | ||
| onRemove(): void; | ||
| isCompatibleWith(layoutParent: any): boolean; | ||
| detachFromSlot(): void; | ||
| freeYogaNode(): void; | ||
| disposeWithoutSlotCascade(): void; | ||
| } | ||
| import { ItalicSpanRenderable } from "./chunk-7fkmdv3h.js"; | ||
| export function Dynamic(props: any): import("solid-js").Accessor<any>; | ||
| import { BoldSpanRenderable } from "./chunk-7fkmdv3h.js"; | ||
| import { Timeline } from "@opentui/core"; | ||
| import { mergeProps } from "solid-js"; | ||
| import { createRenderEffect } from "solid-js"; | ||
| import { BoxRenderable } from "@opentui/core"; | ||
| import { createComponent } from "solid-js"; | ||
| import { TextNodeRenderable } from "@opentui/core"; | ||
| declare class SlotBaseRenderable extends BaseRenderable { | ||
| constructor(id: any); | ||
| add(obj: any, index: any): void; | ||
| remove(id: any): void; | ||
| insertBefore(obj: any, anchor: any): void; | ||
| getRenderable(id: any): void; | ||
| findDescendantById(id: any): void; | ||
| } | ||
| import { TextRenderable } from "@opentui/core"; | ||
| import { BaseRenderable } from "@opentui/core"; | ||
| export { textNodeKeys, mergeProps3 as mergeProps, memo2 as memo, getComponentCatalogue, extend, createComponent2 as createComponent, componentCatalogue, baseComponents, UnderlineSpanRenderable, LinkRenderable, LineBreakRenderable, ItalicSpanRenderable, BoldSpanRenderable }; |
| import { ensureSolidTransformPlugin } from "./solid-plugin.js" | ||
| ensureSolidTransformPlugin() |
| import { plugin as registerBunPlugin } from "bun" | ||
| import * as coreRuntime from "@opentui/core" | ||
| import { | ||
| createRuntimePlugin, | ||
| isCoreRuntimeModuleSpecifier, | ||
| runtimeModuleIdForSpecifier, | ||
| type RuntimeModuleEntry, | ||
| type RuntimePluginRewriteOptions, | ||
| } from "@opentui/core/runtime-plugin" | ||
| import * as solidJsRuntime from "solid-js" | ||
| import * as solidJsStoreRuntime from "solid-js/store" | ||
| import * as solidRuntime from "../index.js" | ||
| import { ensureSolidTransformPlugin } from "./solid-plugin.js" | ||
| const runtimePluginSupportInstalledKey = Symbol.for("opentui.solid.runtime-plugin-support") | ||
| export interface SolidRuntimePluginSupportOptions { | ||
| additional?: Record<string, RuntimeModuleEntry> | ||
| core?: RuntimeModuleEntry | ||
| rewrite?: RuntimePluginRewriteOptions | ||
| } | ||
| interface RuntimePluginSupportInstall { | ||
| specifiers: ReadonlySet<string> | ||
| core: RuntimeModuleEntry | ||
| rewriteKey: string | ||
| } | ||
| type RuntimePluginSupportState = typeof globalThis & { | ||
| [runtimePluginSupportInstalledKey]?: RuntimePluginSupportInstall | ||
| } | ||
| const defaultRuntimeModules: Record<string, RuntimeModuleEntry> = { | ||
| "@opentui/solid": solidRuntime as Record<string, unknown>, | ||
| "solid-js": solidJsRuntime as Record<string, unknown>, | ||
| "solid-js/store": solidJsStoreRuntime as Record<string, unknown>, | ||
| } | ||
| function normalizeRewriteKey(rewrite: RuntimePluginRewriteOptions | undefined): string { | ||
| return `${rewrite?.nodeModulesRuntimeSpecifiers ?? true}:${rewrite?.nodeModulesBareSpecifiers ?? false}` | ||
| } | ||
| function createRuntimeModules(options?: SolidRuntimePluginSupportOptions): Record<string, RuntimeModuleEntry> { | ||
| return { | ||
| ...defaultRuntimeModules, | ||
| ...(options?.additional ?? {}), | ||
| } | ||
| } | ||
| function assertCompatibleInstall( | ||
| install: RuntimePluginSupportInstall, | ||
| modules: Record<string, RuntimeModuleEntry>, | ||
| options?: SolidRuntimePluginSupportOptions, | ||
| ): void { | ||
| for (const specifier of Object.keys(modules)) { | ||
| if (!install.specifiers.has(specifier)) { | ||
| throw new Error( | ||
| `OpenTUI Solid runtime plugin support is already installed without ${specifier}. Call ensureRuntimePluginSupport({ additional }) from @opentui/solid/runtime-plugin-support/configure before importing @opentui/solid/runtime-plugin-support.`, | ||
| ) | ||
| } | ||
| } | ||
| if (options?.core && options.core !== install.core) { | ||
| throw new Error("OpenTUI Solid runtime plugin support is already installed with a different core runtime module.") | ||
| } | ||
| if (options?.rewrite && normalizeRewriteKey(options.rewrite) !== install.rewriteKey) { | ||
| throw new Error("OpenTUI Solid runtime plugin support is already installed with different rewrite options.") | ||
| } | ||
| } | ||
| export function ensureRuntimePluginSupport(options: SolidRuntimePluginSupportOptions = {}): boolean { | ||
| const state = globalThis as RuntimePluginSupportState | ||
| const modules = createRuntimeModules(options) | ||
| const core = options.core ?? (coreRuntime as Record<string, unknown>) | ||
| const rewriteKey = normalizeRewriteKey(options.rewrite) | ||
| const install = state[runtimePluginSupportInstalledKey] | ||
| if (install) { | ||
| assertCompatibleInstall(install, modules, options) | ||
| return false | ||
| } | ||
| ensureSolidTransformPlugin({ | ||
| moduleName: runtimeModuleIdForSpecifier("@opentui/solid"), | ||
| resolvePath(specifier) { | ||
| if (!isCoreRuntimeModuleSpecifier(specifier) && !modules[specifier]) { | ||
| return null | ||
| } | ||
| return runtimeModuleIdForSpecifier(specifier) | ||
| }, | ||
| }) | ||
| registerBunPlugin( | ||
| createRuntimePlugin({ | ||
| core, | ||
| additional: modules, | ||
| rewrite: options.rewrite, | ||
| }), | ||
| ) | ||
| state[runtimePluginSupportInstalledKey] = { | ||
| specifiers: new Set(Object.keys(modules)), | ||
| core, | ||
| rewriteKey, | ||
| } | ||
| return true | ||
| } |
| import { ensureRuntimePluginSupport } from "./runtime-plugin-support-configure.js" | ||
| export { ensureRuntimePluginSupport } | ||
| export type { SolidRuntimePluginSupportOptions } from "./runtime-plugin-support-configure.js" | ||
| ensureRuntimePluginSupport() |
| import { transformAsync } from "@babel/core" | ||
| // @ts-expect-error - Types not important. | ||
| import ts from "@babel/preset-typescript" | ||
| // @ts-expect-error - Types not important. | ||
| import moduleResolver from "babel-plugin-module-resolver" | ||
| // @ts-expect-error - Types not important. | ||
| import solid from "babel-preset-solid" | ||
| import { plugin as registerBunPlugin, type BunPlugin } from "bun" | ||
| export type ResolveImportPath = (specifier: string) => string | null | ||
| const solidTransformStateKey = Symbol.for("opentui.solid.transform") | ||
| type SolidTransformRuntime = { | ||
| moduleName?: string | ||
| resolvePath?: ResolveImportPath | ||
| } | ||
| type SolidTransformState = { | ||
| installed: boolean | ||
| runtime?: SolidTransformRuntime | ||
| } | ||
| type GlobalSolidTransformState = typeof globalThis & { | ||
| [solidTransformStateKey]?: SolidTransformState | ||
| } | ||
| export interface CreateSolidTransformPluginOptions { | ||
| moduleName?: string | ||
| resolvePath?: ResolveImportPath | ||
| } | ||
| const getSolidTransformState = (): SolidTransformState => { | ||
| const state = globalThis as GlobalSolidTransformState | ||
| state[solidTransformStateKey] ??= { installed: false } | ||
| return state[solidTransformStateKey] | ||
| } | ||
| const getSolidTransformRuntime = (): SolidTransformRuntime => { | ||
| return getSolidTransformState().runtime ?? {} | ||
| } | ||
| const sourcePath = (path: string): string => { | ||
| const searchIndex = path.indexOf("?") | ||
| const hashIndex = path.indexOf("#") | ||
| const end = [searchIndex, hashIndex].filter((index) => index >= 0).sort((a, b) => a - b)[0] | ||
| return end === undefined ? path : path.slice(0, end) | ||
| } | ||
| const hasSolidTransformRuntime = (input: CreateSolidTransformPluginOptions): boolean => { | ||
| return input.moduleName !== undefined || input.resolvePath !== undefined | ||
| } | ||
| export function ensureSolidTransformPlugin(input: CreateSolidTransformPluginOptions = {}): boolean { | ||
| const state = getSolidTransformState() | ||
| if (hasSolidTransformRuntime(input)) { | ||
| state.runtime = { | ||
| moduleName: input.moduleName, | ||
| resolvePath: input.resolvePath, | ||
| } | ||
| } | ||
| if (state.installed) { | ||
| return false | ||
| } | ||
| registerBunPlugin(createSolidTransformPlugin()) | ||
| state.installed = true | ||
| return true | ||
| } | ||
| export function resetSolidTransformPluginState(): void { | ||
| const state = getSolidTransformState() | ||
| state.installed = false | ||
| delete state.runtime | ||
| } | ||
| export function createSolidTransformPlugin(input: CreateSolidTransformPluginOptions = {}): BunPlugin { | ||
| return { | ||
| name: "bun-plugin-solid", | ||
| setup: (build) => { | ||
| build.onLoad({ filter: /[/\\]node_modules[/\\]solid-js[/\\]dist[/\\]server\.js(?:[?#].*)?$/ }, async (args) => { | ||
| const path = sourcePath(args.path).replace("server.js", "solid.js") | ||
| const file = Bun.file(path) | ||
| const code = await file.text() | ||
| return { contents: code, loader: "js" } | ||
| }) | ||
| build.onLoad( | ||
| { filter: /[/\\]node_modules[/\\]solid-js[/\\]store[/\\]dist[/\\]server\.js(?:[?#].*)?$/ }, | ||
| async (args) => { | ||
| const path = sourcePath(args.path).replace("server.js", "store.js") | ||
| const file = Bun.file(path) | ||
| const code = await file.text() | ||
| return { contents: code, loader: "js" } | ||
| }, | ||
| ) | ||
| build.onLoad({ filter: /\.(js|ts)x(?:[?#].*)?$/ }, async (args) => { | ||
| const path = sourcePath(args.path) | ||
| const file = Bun.file(path) | ||
| const code = await file.text() | ||
| const runtime = getSolidTransformRuntime() | ||
| const moduleName = input.moduleName ?? runtime.moduleName ?? "@opentui/solid" | ||
| const resolvePath = input.resolvePath ?? runtime.resolvePath | ||
| const plugins = resolvePath | ||
| ? [ | ||
| [ | ||
| moduleResolver, | ||
| { | ||
| resolvePath(specifier: string) { | ||
| return resolvePath(specifier) ?? specifier | ||
| }, | ||
| }, | ||
| ], | ||
| ] | ||
| : [] | ||
| const transforms = await transformAsync(code, { | ||
| filename: path, | ||
| configFile: false, | ||
| babelrc: false, | ||
| plugins, | ||
| presets: [ | ||
| [ | ||
| solid, | ||
| { | ||
| moduleName, | ||
| generate: "universal", | ||
| }, | ||
| ], | ||
| [ts], | ||
| ], | ||
| }) | ||
| return { | ||
| contents: transforms?.code ?? "", | ||
| loader: "js", | ||
| } | ||
| }) | ||
| }, | ||
| } | ||
| } | ||
| const solidTransformPlugin = createSolidTransformPlugin() | ||
| export default solidTransformPlugin |
333503
249.59%50
56.25%4041
60.8%2
100%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated