@opentui/solid 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/components.js +106 -4
  2. package/components.js.map +10 -0
  3. package/index.bun.js +1609 -0
  4. package/index.bun.js.map +22 -0
  5. package/index.d.ts +1 -1
  6. package/index.js +146 -72
  7. package/index.js.map +22 -0
  8. package/jsx-dev-runtime.d.ts +1 -0
  9. package/jsx-dev-runtime.js +2 -0
  10. package/jsx-dev-runtime.js.map +1 -0
  11. package/jsx-runtime.d.ts +9 -6
  12. package/jsx-runtime.js +31 -0
  13. package/jsx-runtime.js.map +1 -0
  14. package/package.json +27 -9
  15. package/scripts/preload.js +3 -0
  16. package/scripts/preload.js.map +1 -0
  17. package/scripts/preload.node.js +9 -0
  18. package/scripts/runtime-plugin-support-configure.js +67 -0
  19. package/scripts/runtime-plugin-support-configure.js.map +1 -0
  20. package/scripts/runtime-plugin-support-configure.node.js +11 -0
  21. package/scripts/runtime-plugin-support.js +4 -0
  22. package/scripts/runtime-plugin-support.js.map +1 -0
  23. package/scripts/runtime-plugin-support.node.js +11 -0
  24. package/scripts/solid-plugin.d.ts +1 -1
  25. package/scripts/solid-plugin.js +76 -0
  26. package/scripts/solid-plugin.js.map +1 -0
  27. package/scripts/solid-plugin.node.js +21 -0
  28. package/scripts/solid-transform.d.ts +10 -0
  29. package/scripts/solid-transform.js +66 -0
  30. package/scripts/solid-transform.js.map +1 -0
  31. package/src/elements/extras.d.ts +2 -2
  32. package/src/testing/bun-test-node.d.ts +12 -0
  33. package/src/types/elements.d.ts +1 -1
  34. package/chunk-7fkmdv3h.js +0 -110
  35. package/dist/chunk-7fkmdv3h.d.ts +0 -81
  36. package/dist/index.d.ts +0 -118
  37. package/scripts/preload.ts +0 -3
  38. package/scripts/runtime-plugin-support-configure.ts +0 -109
  39. package/scripts/runtime-plugin-support.ts +0 -6
  40. package/scripts/solid-plugin.ts +0 -148
package/index.bun.js ADDED
@@ -0,0 +1,1609 @@
1
+ // @bun
2
+ // index.ts
3
+ import { CliRenderer, createCliRenderer, engine as engine2 } from "@opentui/core";
4
+ import { createTestRenderer } from "@opentui/core/testing";
5
+
6
+ // src/elements/catalogue.ts
7
+ import {
8
+ ASCIIFontRenderable,
9
+ BoxRenderable,
10
+ CodeRenderable,
11
+ DiffRenderable,
12
+ InputRenderable,
13
+ LineNumberRenderable,
14
+ MarkdownRenderable,
15
+ ScrollBoxRenderable,
16
+ SelectRenderable,
17
+ TabSelectRenderable,
18
+ TextareaRenderable,
19
+ TextAttributes,
20
+ TextNodeRenderable,
21
+ TextRenderable
22
+ } from "@opentui/core";
23
+
24
+ class SpanRenderable extends TextNodeRenderable {
25
+ _ctx;
26
+ constructor(_ctx, options) {
27
+ super(options);
28
+ this._ctx = _ctx;
29
+ }
30
+ }
31
+ var textNodeKeys = ["span", "b", "strong", "i", "em", "u", "a"];
32
+
33
+ class TextModifierRenderable extends SpanRenderable {
34
+ constructor(options, modifier) {
35
+ super(null, options);
36
+ if (modifier === "b" || modifier === "strong") {
37
+ this.attributes = (this.attributes || 0) | TextAttributes.BOLD;
38
+ } else if (modifier === "i" || modifier === "em") {
39
+ this.attributes = (this.attributes || 0) | TextAttributes.ITALIC;
40
+ } else if (modifier === "u") {
41
+ this.attributes = (this.attributes || 0) | TextAttributes.UNDERLINE;
42
+ }
43
+ }
44
+ }
45
+
46
+ class BoldSpanRenderable extends TextModifierRenderable {
47
+ constructor(options) {
48
+ super(options, "b");
49
+ }
50
+ }
51
+
52
+ class ItalicSpanRenderable extends TextModifierRenderable {
53
+ constructor(options) {
54
+ super(options, "i");
55
+ }
56
+ }
57
+
58
+ class UnderlineSpanRenderable extends TextModifierRenderable {
59
+ constructor(options) {
60
+ super(options, "u");
61
+ }
62
+ }
63
+
64
+ class LineBreakRenderable extends SpanRenderable {
65
+ constructor(_ctx, options) {
66
+ super(null, options);
67
+ this.add();
68
+ }
69
+ add() {
70
+ return super.add(`
71
+ `);
72
+ }
73
+ }
74
+
75
+ class LinkRenderable extends SpanRenderable {
76
+ constructor(_ctx, options) {
77
+ const linkOptions = {
78
+ ...options,
79
+ link: { url: options.href }
80
+ };
81
+ super(null, linkOptions);
82
+ }
83
+ }
84
+ var baseComponents = {
85
+ box: BoxRenderable,
86
+ text: TextRenderable,
87
+ input: InputRenderable,
88
+ select: SelectRenderable,
89
+ textarea: TextareaRenderable,
90
+ ascii_font: ASCIIFontRenderable,
91
+ tab_select: TabSelectRenderable,
92
+ scrollbox: ScrollBoxRenderable,
93
+ code: CodeRenderable,
94
+ diff: DiffRenderable,
95
+ line_number: LineNumberRenderable,
96
+ markdown: MarkdownRenderable,
97
+ span: SpanRenderable,
98
+ strong: BoldSpanRenderable,
99
+ b: BoldSpanRenderable,
100
+ em: ItalicSpanRenderable,
101
+ i: ItalicSpanRenderable,
102
+ u: UnderlineSpanRenderable,
103
+ br: LineBreakRenderable,
104
+ a: LinkRenderable
105
+ };
106
+ var componentCatalogue = { ...baseComponents };
107
+ function extend(objects) {
108
+ Object.assign(componentCatalogue, objects);
109
+ }
110
+ function getComponentCatalogue() {
111
+ return componentCatalogue;
112
+ }
113
+ // src/elements/hooks.ts
114
+ import {
115
+ engine,
116
+ Timeline
117
+ } from "@opentui/core";
118
+ import { createContext, createSignal, onCleanup, onMount, useContext } from "solid-js";
119
+ var RendererContext = createContext();
120
+ var useRenderer = () => {
121
+ const renderer = useContext(RendererContext);
122
+ if (!renderer) {
123
+ throw new Error("No renderer found");
124
+ }
125
+ return renderer;
126
+ };
127
+ var onResize = (callback) => {
128
+ const renderer = useRenderer();
129
+ onMount(() => {
130
+ renderer.on("resize", callback);
131
+ });
132
+ onCleanup(() => {
133
+ renderer.off("resize", callback);
134
+ });
135
+ };
136
+ var useTerminalDimensions = () => {
137
+ const renderer = useRenderer();
138
+ const [terminalDimensions, setTerminalDimensions] = createSignal({ width: renderer.width, height: renderer.height });
139
+ const callback = (width, height) => {
140
+ setTerminalDimensions({ width, height });
141
+ };
142
+ onResize(callback);
143
+ return terminalDimensions;
144
+ };
145
+ var useKeyboard = (callback, options) => {
146
+ const renderer = useRenderer();
147
+ const keyHandler = renderer.keyInput;
148
+ onMount(() => {
149
+ keyHandler.on("keypress", callback);
150
+ if (options?.release) {
151
+ keyHandler.on("keyrelease", callback);
152
+ }
153
+ });
154
+ onCleanup(() => {
155
+ keyHandler.off("keypress", callback);
156
+ if (options?.release) {
157
+ keyHandler.off("keyrelease", callback);
158
+ }
159
+ });
160
+ };
161
+ var usePaste = (callback) => {
162
+ const renderer = useRenderer();
163
+ const keyHandler = renderer.keyInput;
164
+ onMount(() => {
165
+ keyHandler.on("paste", callback);
166
+ });
167
+ onCleanup(() => {
168
+ keyHandler.off("paste", callback);
169
+ });
170
+ };
171
+ var useKeyHandler = useKeyboard;
172
+ var onFocus = (callback) => {
173
+ const renderer = useRenderer();
174
+ onMount(() => {
175
+ renderer.on("focus", callback);
176
+ });
177
+ onCleanup(() => {
178
+ renderer.off("focus", callback);
179
+ });
180
+ };
181
+ var onBlur = (callback) => {
182
+ const renderer = useRenderer();
183
+ onMount(() => {
184
+ renderer.on("blur", callback);
185
+ });
186
+ onCleanup(() => {
187
+ renderer.off("blur", callback);
188
+ });
189
+ };
190
+ var useSelectionHandler = (callback) => {
191
+ const renderer = useRenderer();
192
+ onMount(() => {
193
+ renderer.on("selection", callback);
194
+ });
195
+ onCleanup(() => {
196
+ renderer.off("selection", callback);
197
+ });
198
+ };
199
+ var useTimeline = (options = {}) => {
200
+ const timeline = new Timeline(options);
201
+ onMount(() => {
202
+ if (options.autoplay !== false) {
203
+ timeline.play();
204
+ }
205
+ engine.register(timeline);
206
+ });
207
+ onCleanup(() => {
208
+ timeline.pause();
209
+ engine.unregister(timeline);
210
+ });
211
+ return timeline;
212
+ };
213
+ // src/elements/extras.ts
214
+ import { createEffect, createMemo as createMemo2, getOwner, onCleanup as onCleanup2, runWithOwner, splitProps, untrack as untrack2 } from "solid-js";
215
+
216
+ // src/reconciler.ts
217
+ import {
218
+ BaseRenderable,
219
+ createTextAttributes,
220
+ InputRenderable as InputRenderable2,
221
+ InputRenderableEvents,
222
+ isTextNodeRenderable,
223
+ parseColor,
224
+ Renderable,
225
+ RootTextNodeRenderable,
226
+ ScrollBoxRenderable as ScrollBoxRenderable2,
227
+ SelectRenderable as SelectRenderable2,
228
+ SelectRenderableEvents,
229
+ TabSelectRenderable as TabSelectRenderable2,
230
+ TabSelectRenderableEvents,
231
+ TextNodeRenderable as TextNodeRenderable2,
232
+ TextRenderable as TextRenderable2
233
+ } from "@opentui/core";
234
+ import { decodeHTML } from "entities";
235
+ import { useContext as useContext2 } from "solid-js";
236
+
237
+ // src/renderer/universal.js
238
+ import { createRoot, createRenderEffect, createMemo, createComponent, untrack, mergeProps } from "solid-js";
239
+ var memo = (fn) => createMemo(() => fn());
240
+ function createRenderer({
241
+ createElement,
242
+ createTextNode,
243
+ createSlotNode,
244
+ isTextNode,
245
+ replaceText,
246
+ insertNode,
247
+ removeNode,
248
+ setProperty,
249
+ getParentNode,
250
+ getFirstChild,
251
+ getNextSibling
252
+ }) {
253
+ function insert(parent, accessor, marker, initial) {
254
+ if (marker !== undefined && !initial)
255
+ initial = [];
256
+ if (typeof accessor !== "function")
257
+ return insertExpression(parent, accessor, initial, marker);
258
+ createRenderEffect((current) => insertExpression(parent, accessor(), current, marker), initial);
259
+ }
260
+ function insertExpression(parent, value, current, marker, unwrapArray) {
261
+ while (typeof current === "function")
262
+ current = current();
263
+ if (value === current)
264
+ return current;
265
+ const t = typeof value, multi = marker !== undefined;
266
+ if (t === "string" || t === "number") {
267
+ if (t === "number")
268
+ value = value.toString();
269
+ if (multi) {
270
+ let node = current[0];
271
+ if (node && isTextNode(node)) {
272
+ replaceText(node, value);
273
+ } else
274
+ node = createTextNode(value);
275
+ current = cleanChildren(parent, current, marker, node);
276
+ } else {
277
+ if (current !== "" && typeof current === "string") {
278
+ replaceText(getFirstChild(parent), current = value);
279
+ } else {
280
+ cleanChildren(parent, current, marker, createTextNode(value));
281
+ current = value;
282
+ }
283
+ }
284
+ } else if (value == null || t === "boolean") {
285
+ current = cleanChildren(parent, current, marker);
286
+ } else if (t === "function") {
287
+ createRenderEffect(() => {
288
+ let v = value();
289
+ while (typeof v === "function")
290
+ v = v();
291
+ current = insertExpression(parent, v, current, marker);
292
+ });
293
+ return () => current;
294
+ } else if (Array.isArray(value)) {
295
+ const array = [];
296
+ if (normalizeIncomingArray(array, value, unwrapArray)) {
297
+ createRenderEffect(() => current = insertExpression(parent, array, current, marker, true));
298
+ return () => current;
299
+ }
300
+ if (array.length === 0) {
301
+ const replacement = cleanChildren(parent, current, marker);
302
+ if (multi)
303
+ return current = replacement;
304
+ } else {
305
+ if (Array.isArray(current)) {
306
+ if (current.length === 0) {
307
+ appendNodes(parent, array, marker);
308
+ } else
309
+ reconcileArrays(parent, current, array);
310
+ } else if (current == null || current === "") {
311
+ appendNodes(parent, array);
312
+ } else {
313
+ reconcileArrays(parent, multi && current || [getFirstChild(parent)], array);
314
+ }
315
+ }
316
+ current = array;
317
+ } else {
318
+ if (Array.isArray(current)) {
319
+ if (multi)
320
+ return current = cleanChildren(parent, current, marker, value);
321
+ cleanChildren(parent, current, null, value);
322
+ } else if (current == null || current === "" || !getFirstChild(parent)) {
323
+ insertNode(parent, value);
324
+ } else
325
+ replaceNode(parent, value, getFirstChild(parent));
326
+ current = value;
327
+ }
328
+ return current;
329
+ }
330
+ function normalizeIncomingArray(normalized, array, unwrap) {
331
+ let dynamic = false;
332
+ for (let i = 0, len = array.length;i < len; i++) {
333
+ let item = array[i], t;
334
+ if (item == null || item === true || item === false)
335
+ ;
336
+ else if (Array.isArray(item)) {
337
+ dynamic = normalizeIncomingArray(normalized, item) || dynamic;
338
+ } else if ((t = typeof item) === "string" || t === "number") {
339
+ normalized.push(createTextNode(item));
340
+ } else if (t === "function") {
341
+ if (unwrap) {
342
+ while (typeof item === "function")
343
+ item = item();
344
+ dynamic = normalizeIncomingArray(normalized, Array.isArray(item) ? item : [item]) || dynamic;
345
+ } else {
346
+ normalized.push(item);
347
+ dynamic = true;
348
+ }
349
+ } else
350
+ normalized.push(item);
351
+ }
352
+ return dynamic;
353
+ }
354
+ function reconcileArrays(parentNode, a, b) {
355
+ let bLength = b.length, aEnd = a.length, bEnd = bLength, aStart = 0, bStart = 0, after = getNextSibling(a[aEnd - 1]), map = null;
356
+ while (aStart < aEnd || bStart < bEnd) {
357
+ if (a[aStart] === b[bStart]) {
358
+ aStart++;
359
+ bStart++;
360
+ continue;
361
+ }
362
+ while (a[aEnd - 1] === b[bEnd - 1]) {
363
+ aEnd--;
364
+ bEnd--;
365
+ }
366
+ if (aEnd === aStart) {
367
+ const node = bEnd < bLength ? bStart ? getNextSibling(b[bStart - 1]) : b[bEnd - bStart] : after;
368
+ while (bStart < bEnd)
369
+ insertNode(parentNode, b[bStart++], node);
370
+ } else if (bEnd === bStart) {
371
+ while (aStart < aEnd) {
372
+ if (!map || !map.has(a[aStart]))
373
+ removeNode(parentNode, a[aStart]);
374
+ aStart++;
375
+ }
376
+ } else if (a[aStart] === b[bEnd - 1] && b[bStart] === a[aEnd - 1]) {
377
+ const node = getNextSibling(a[--aEnd]);
378
+ insertNode(parentNode, b[bStart++], getNextSibling(a[aStart++]));
379
+ insertNode(parentNode, b[--bEnd], node);
380
+ a[aEnd] = b[bEnd];
381
+ } else {
382
+ if (!map) {
383
+ map = new Map;
384
+ let i = bStart;
385
+ while (i < bEnd)
386
+ map.set(b[i], i++);
387
+ }
388
+ const index = map.get(a[aStart]);
389
+ if (index != null) {
390
+ if (bStart < index && index < bEnd) {
391
+ let i = aStart, sequence = 1, t;
392
+ while (++i < aEnd && i < bEnd) {
393
+ if ((t = map.get(a[i])) == null || t !== index + sequence)
394
+ break;
395
+ sequence++;
396
+ }
397
+ if (sequence > index - bStart) {
398
+ const node = a[aStart];
399
+ while (bStart < index)
400
+ insertNode(parentNode, b[bStart++], node);
401
+ } else
402
+ replaceNode(parentNode, b[bStart++], a[aStart++]);
403
+ } else
404
+ aStart++;
405
+ } else
406
+ removeNode(parentNode, a[aStart++]);
407
+ }
408
+ }
409
+ }
410
+ function cleanChildren(parent, current, marker, replacement) {
411
+ if (marker === undefined) {
412
+ let removed;
413
+ while (removed = getFirstChild(parent))
414
+ removeNode(parent, removed);
415
+ replacement && insertNode(parent, replacement);
416
+ return replacement ?? "";
417
+ }
418
+ const node = replacement || createSlotNode();
419
+ if (current.length) {
420
+ let inserted = false;
421
+ for (let i = current.length - 1;i >= 0; i--) {
422
+ const el = current[i];
423
+ if (node !== el) {
424
+ const isParent = getParentNode(el) === parent;
425
+ if (!inserted && !i)
426
+ isParent ? replaceNode(parent, node, el) : insertNode(parent, node, marker);
427
+ else
428
+ isParent && removeNode(parent, el);
429
+ } else
430
+ inserted = true;
431
+ }
432
+ } else
433
+ insertNode(parent, node, marker);
434
+ return [node];
435
+ }
436
+ function appendNodes(parent, array, marker) {
437
+ for (let i = 0, len = array.length;i < len; i++)
438
+ insertNode(parent, array[i], marker);
439
+ }
440
+ function replaceNode(parent, newNode, oldNode) {
441
+ insertNode(parent, newNode, oldNode);
442
+ removeNode(parent, oldNode);
443
+ }
444
+ function spreadExpression(node, props, prevProps = {}, skipChildren) {
445
+ props || (props = {});
446
+ if (!skipChildren) {
447
+ createRenderEffect(() => prevProps.children = insertExpression(node, props.children, prevProps.children));
448
+ }
449
+ createRenderEffect(() => props.ref && props.ref(node));
450
+ createRenderEffect(() => {
451
+ for (const prop in props) {
452
+ if (prop === "children" || prop === "ref")
453
+ continue;
454
+ const value = props[prop];
455
+ if (value === prevProps[prop])
456
+ continue;
457
+ setProperty(node, prop, value, prevProps[prop]);
458
+ prevProps[prop] = value;
459
+ }
460
+ });
461
+ return prevProps;
462
+ }
463
+ return {
464
+ render(code, element) {
465
+ let disposer;
466
+ createRoot((dispose) => {
467
+ disposer = dispose;
468
+ insert(element, code());
469
+ });
470
+ return disposer;
471
+ },
472
+ insert,
473
+ spread(node, accessor, skipChildren) {
474
+ if (typeof accessor === "function") {
475
+ createRenderEffect((current) => spreadExpression(node, accessor(), current, skipChildren));
476
+ } else
477
+ spreadExpression(node, accessor, undefined, skipChildren);
478
+ },
479
+ createElement,
480
+ createTextNode,
481
+ insertNode,
482
+ setProp(node, name, value, prev) {
483
+ setProperty(node, name, value, prev);
484
+ return value;
485
+ },
486
+ mergeProps,
487
+ effect: createRenderEffect,
488
+ memo,
489
+ createComponent,
490
+ use(fn, element, arg) {
491
+ return untrack(() => fn(element, arg));
492
+ }
493
+ };
494
+ }
495
+
496
+ // src/renderer/index.ts
497
+ import { mergeProps as mergeProps2 } from "solid-js";
498
+ function createRenderer2(options) {
499
+ const renderer = createRenderer(options);
500
+ renderer.mergeProps = mergeProps2;
501
+ return renderer;
502
+ }
503
+
504
+ // src/utils/id-counter.ts
505
+ var idCounter = new Map;
506
+ function getNextId(elementType) {
507
+ if (!idCounter.has(elementType)) {
508
+ idCounter.set(elementType, 0);
509
+ }
510
+ const value = idCounter.get(elementType) + 1;
511
+ idCounter.set(elementType, value);
512
+ return `${elementType}-${value}`;
513
+ }
514
+
515
+ // src/utils/log.ts
516
+ var log = (...args) => {
517
+ if (process.env.DEBUG) {
518
+ console.log("[Reconciler]", ...args);
519
+ }
520
+ };
521
+
522
+ // src/reconciler.ts
523
+ class TextNode extends TextNodeRenderable2 {
524
+ static fromString(text, options = {}) {
525
+ const node = new TextNode(options);
526
+ node.add(text);
527
+ return node;
528
+ }
529
+ }
530
+ var logId = (node) => {
531
+ if (!node)
532
+ return;
533
+ return node.id;
534
+ };
535
+ var getNodeChildren = (node) => {
536
+ let children;
537
+ if (node instanceof TextRenderable2) {
538
+ children = node.getTextChildren();
539
+ } else {
540
+ children = node.getChildren();
541
+ }
542
+ return children;
543
+ };
544
+ function _insertNode(parent, node, anchor) {
545
+ log("Inserting node:", logId(node), "into parent:", logId(parent), "with anchor:", logId(anchor), node instanceof TextNode);
546
+ if (node instanceof SlotRenderable) {
547
+ node.parent = parent;
548
+ node = node.getSlotChild(parent);
549
+ }
550
+ if (anchor && anchor instanceof SlotRenderable) {
551
+ anchor = anchor.getSlotChild(parent);
552
+ }
553
+ if (isTextNodeRenderable(node)) {
554
+ if (!(parent instanceof TextRenderable2) && !isTextNodeRenderable(parent)) {
555
+ 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}`);
556
+ }
557
+ }
558
+ if (!(parent instanceof BaseRenderable)) {
559
+ console.error("[INSERT]", "Tried to mount a non base renderable");
560
+ throw new Error("Tried to mount a non base renderable");
561
+ }
562
+ if (!anchor) {
563
+ parent.add(node);
564
+ return;
565
+ }
566
+ const children = getNodeChildren(parent);
567
+ const anchorIndex = children.findIndex((el) => el.id === anchor.id);
568
+ if (anchorIndex === -1) {
569
+ log("[INSERT]", "Could not find anchor", logId(parent), logId(anchor), "[children]", ...children.map((c) => c.id));
570
+ }
571
+ parent.add(node, anchorIndex);
572
+ }
573
+ function _removeNode(parent, node) {
574
+ log("Removing node:", logId(node), "from parent:", logId(parent));
575
+ let slotParent;
576
+ if (node instanceof SlotRenderable) {
577
+ slotParent = node;
578
+ const slotChild = slotParent.getSlotChildForRemoval(parent);
579
+ if (!slotChild) {
580
+ if (slotParent.parent === parent) {
581
+ slotParent.parent = null;
582
+ }
583
+ return;
584
+ }
585
+ node = slotChild;
586
+ }
587
+ parent.remove(node.id);
588
+ slotParent?.didRemoveSlotChild(parent, node);
589
+ process.nextTick(() => {
590
+ if (node instanceof BaseRenderable && !node.parent) {
591
+ node.destroyRecursively();
592
+ return;
593
+ }
594
+ });
595
+ }
596
+ function _createTextNode(value) {
597
+ log("Creating text node:", value);
598
+ const id = getNextId("text-node");
599
+ if (typeof value === "number") {
600
+ value = value.toString();
601
+ }
602
+ return TextNode.fromString(decodeHTML(value), { id });
603
+ }
604
+ function createSlotNode() {
605
+ const id = getNextId("slot-node");
606
+ log("Creating slot node", id);
607
+ return new SlotRenderable(id);
608
+ }
609
+ function _getParentNode(childNode) {
610
+ log("Getting parent of node:", logId(childNode));
611
+ let parent = childNode.parent ?? undefined;
612
+ if (parent instanceof RootTextNodeRenderable) {
613
+ parent = parent.textParent ?? undefined;
614
+ }
615
+ const scrollBoxCandidate = parent?.parent?.parent?.parent;
616
+ if (scrollBoxCandidate instanceof ScrollBoxRenderable2 && scrollBoxCandidate.content === parent) {
617
+ parent = scrollBoxCandidate;
618
+ }
619
+ return parent;
620
+ }
621
+ var {
622
+ render: _render,
623
+ effect,
624
+ memo: memo2,
625
+ createComponent: createComponent2,
626
+ createElement,
627
+ createTextNode,
628
+ insertNode,
629
+ insert,
630
+ spread,
631
+ setProp,
632
+ mergeProps: mergeProps3,
633
+ use
634
+ } = createRenderer2({
635
+ createElement(tagName) {
636
+ log("Creating element:", tagName);
637
+ const id = getNextId(tagName);
638
+ const solidRenderer = useContext2(RendererContext);
639
+ if (!solidRenderer) {
640
+ throw new Error("No renderer found");
641
+ }
642
+ const elements = getComponentCatalogue();
643
+ if (!elements[tagName]) {
644
+ throw new Error(`[Reconciler] Unknown component type: ${tagName}`);
645
+ }
646
+ const element = new elements[tagName](solidRenderer, { id });
647
+ log("Element created with id:", id);
648
+ return element;
649
+ },
650
+ createTextNode: _createTextNode,
651
+ createSlotNode,
652
+ replaceText(textNode, value) {
653
+ log("Replacing text:", value, "in node:", logId(textNode));
654
+ if (!(textNode instanceof TextNode))
655
+ return;
656
+ textNode.replace(decodeHTML(value), 0);
657
+ },
658
+ setProperty(node, name, value, prev) {
659
+ if (name.startsWith("on:")) {
660
+ const eventName = name.slice(3);
661
+ if (value) {
662
+ node.on(eventName, value);
663
+ }
664
+ if (prev) {
665
+ node.off(eventName, prev);
666
+ }
667
+ return;
668
+ }
669
+ if (isTextNodeRenderable(node)) {
670
+ if (name === "href") {
671
+ node.link = { url: value };
672
+ return;
673
+ }
674
+ if (name === "style") {
675
+ node.attributes |= createTextAttributes(value);
676
+ node.fg = value.fg ? parseColor(value.fg) : node.fg;
677
+ node.bg = value.bg ? parseColor(value.bg) : node.bg;
678
+ return;
679
+ }
680
+ return;
681
+ }
682
+ switch (name) {
683
+ case "id":
684
+ log("Id mapped", node.id, "=", value);
685
+ node[name] = value;
686
+ break;
687
+ case "focused":
688
+ if (!(node instanceof Renderable))
689
+ return;
690
+ if (value) {
691
+ node.focus();
692
+ } else {
693
+ node.blur();
694
+ }
695
+ break;
696
+ case "onChange":
697
+ let event = undefined;
698
+ if (node instanceof SelectRenderable2) {
699
+ event = SelectRenderableEvents.SELECTION_CHANGED;
700
+ } else if (node instanceof TabSelectRenderable2) {
701
+ event = TabSelectRenderableEvents.SELECTION_CHANGED;
702
+ } else if (node instanceof InputRenderable2) {
703
+ event = InputRenderableEvents.CHANGE;
704
+ }
705
+ if (!event)
706
+ break;
707
+ if (value) {
708
+ node.on(event, value);
709
+ }
710
+ if (prev) {
711
+ node.off(event, prev);
712
+ }
713
+ break;
714
+ case "onInput":
715
+ if (node instanceof InputRenderable2) {
716
+ if (value) {
717
+ node.on(InputRenderableEvents.INPUT, value);
718
+ }
719
+ if (prev) {
720
+ node.off(InputRenderableEvents.INPUT, prev);
721
+ }
722
+ }
723
+ break;
724
+ case "onSubmit":
725
+ if (node instanceof InputRenderable2) {
726
+ if (value) {
727
+ node.on(InputRenderableEvents.ENTER, value);
728
+ }
729
+ if (prev) {
730
+ node.off(InputRenderableEvents.ENTER, prev);
731
+ }
732
+ } else {
733
+ node[name] = value;
734
+ }
735
+ break;
736
+ case "onSelect":
737
+ if (node instanceof SelectRenderable2) {
738
+ if (value) {
739
+ node.on(SelectRenderableEvents.ITEM_SELECTED, value);
740
+ }
741
+ if (prev) {
742
+ node.off(SelectRenderableEvents.ITEM_SELECTED, prev);
743
+ }
744
+ } else if (node instanceof TabSelectRenderable2) {
745
+ if (value) {
746
+ node.on(TabSelectRenderableEvents.ITEM_SELECTED, value);
747
+ }
748
+ if (prev) {
749
+ node.off(TabSelectRenderableEvents.ITEM_SELECTED, prev);
750
+ }
751
+ }
752
+ break;
753
+ case "style":
754
+ for (const prop in value) {
755
+ const propVal = value[prop];
756
+ if (prev !== undefined && propVal === prev[prop])
757
+ continue;
758
+ node[prop] = propVal;
759
+ }
760
+ break;
761
+ case "text":
762
+ case "content": {
763
+ const textValue = typeof value === "string" ? value : Array.isArray(value) ? value.join("") : `${value}`;
764
+ node[name] = decodeHTML(textValue);
765
+ break;
766
+ }
767
+ default:
768
+ node[name] = value;
769
+ }
770
+ },
771
+ isTextNode(node) {
772
+ return node instanceof TextNode;
773
+ },
774
+ insertNode: _insertNode,
775
+ removeNode: _removeNode,
776
+ getParentNode: _getParentNode,
777
+ getFirstChild(node) {
778
+ log("Getting first child of node:", logId(node));
779
+ const firstChild = getNodeChildren(node)[0];
780
+ if (!firstChild) {
781
+ log("No first child found for node:", logId(node));
782
+ return;
783
+ }
784
+ log("First child found:", logId(firstChild), "for node:", logId(node));
785
+ return firstChild;
786
+ },
787
+ getNextSibling(node) {
788
+ log("Getting next sibling of node:", logId(node));
789
+ const parent = _getParentNode(node);
790
+ if (!parent) {
791
+ log("No parent found for node:", logId(node));
792
+ return;
793
+ }
794
+ if (node instanceof SlotRenderable) {
795
+ const layoutSlotNode = node.getSlotChildForRemoval(parent);
796
+ if (layoutSlotNode) {
797
+ node = layoutSlotNode;
798
+ }
799
+ }
800
+ const siblings = getNodeChildren(parent);
801
+ const index = siblings.indexOf(node);
802
+ if (index === -1 || index === siblings.length - 1) {
803
+ log("No next sibling found for node:", logId(node));
804
+ return;
805
+ }
806
+ const nextSibling = siblings[index + 1];
807
+ if (!nextSibling) {
808
+ log("Next sibling is null for node:", logId(node));
809
+ return;
810
+ }
811
+ log("Next sibling found:", logId(nextSibling), "for node:", logId(node));
812
+ return nextSibling;
813
+ }
814
+ });
815
+
816
+ // src/elements/extras.ts
817
+ function Portal(props) {
818
+ const renderer = useRenderer();
819
+ const marker = createSlotNode(), mount = () => props.mount || renderer.root, owner = getOwner();
820
+ let content;
821
+ createEffect(() => {
822
+ content || (content = runWithOwner(owner, () => createMemo2(() => props.children)));
823
+ const el = mount();
824
+ const container = createElement("box"), renderRoot = container;
825
+ Object.defineProperty(container, "_$host", {
826
+ get() {
827
+ return marker.parent;
828
+ },
829
+ configurable: true
830
+ });
831
+ insert(renderRoot, content);
832
+ el.add(container);
833
+ props.ref && props.ref(container);
834
+ onCleanup2(() => el.remove(container.id));
835
+ }, undefined, { render: true });
836
+ return marker;
837
+ }
838
+ function createDynamic(component, props) {
839
+ const cached = createMemo2(component);
840
+ return createMemo2(() => {
841
+ const component2 = cached();
842
+ switch (typeof component2) {
843
+ case "function":
844
+ return untrack2(() => component2(props));
845
+ case "string":
846
+ const el = createElement(component2);
847
+ spread(el, props);
848
+ return el;
849
+ default:
850
+ break;
851
+ }
852
+ });
853
+ }
854
+ function Dynamic(props) {
855
+ const [, others] = splitProps(props, ["component"]);
856
+ return createDynamic(() => props.component, others);
857
+ }
858
+ // src/elements/slot.ts
859
+ import { BaseRenderable as BaseRenderable2, isTextNodeRenderable as isTextNodeRenderable2, TextNodeRenderable as TextNodeRenderable3, TextRenderable as TextRenderable3, Yoga } from "@opentui/core";
860
+ function getLayoutNodeConstructor(parent) {
861
+ const parentLayoutNode = parent?.getLayoutNode?.();
862
+ return parentLayoutNode?.constructor;
863
+ }
864
+ function createLayoutSlotYogaNode(parentNodeConstructor) {
865
+ return parentNodeConstructor?.create?.() ?? Yoga.default.Node.create();
866
+ }
867
+
868
+ class SlotBaseRenderable extends BaseRenderable2 {
869
+ constructor(id) {
870
+ super({
871
+ id
872
+ });
873
+ }
874
+ add(obj, index) {
875
+ throw new Error("Can't add children on an Slot renderable");
876
+ }
877
+ getChildren() {
878
+ return [];
879
+ }
880
+ remove(id) {}
881
+ insertBefore(obj, anchor) {
882
+ throw new Error("Can't add children on an Slot renderable");
883
+ }
884
+ getRenderable(id) {
885
+ return;
886
+ }
887
+ getChildrenCount() {
888
+ return 0;
889
+ }
890
+ requestRender() {}
891
+ findDescendantById(id) {
892
+ return;
893
+ }
894
+ }
895
+
896
+ class TextSlotRenderable extends TextNodeRenderable3 {
897
+ slotParent;
898
+ destroyed = false;
899
+ constructor(id, parent) {
900
+ super({ id });
901
+ this._visible = false;
902
+ this.slotParent = parent;
903
+ }
904
+ detachFromSlot() {
905
+ this.slotParent = undefined;
906
+ }
907
+ disposeWithoutSlotCascade() {
908
+ if (this.destroyed) {
909
+ return;
910
+ }
911
+ this.destroyed = true;
912
+ this.detachFromSlot();
913
+ }
914
+ destroy() {
915
+ if (this.destroyed) {
916
+ return;
917
+ }
918
+ this.destroyed = true;
919
+ const slotParent = this.slotParent;
920
+ this.slotParent = undefined;
921
+ slotParent?.destroy();
922
+ super.destroy();
923
+ }
924
+ }
925
+
926
+ class LayoutSlotRenderable extends SlotBaseRenderable {
927
+ yogaNode;
928
+ slotParent;
929
+ destroyed = false;
930
+ yogaNodeConstructor;
931
+ yogaNodeFreed = false;
932
+ constructor(id, parent, layoutParent) {
933
+ super(id);
934
+ this._visible = false;
935
+ this.slotParent = parent;
936
+ this.yogaNodeConstructor = getLayoutNodeConstructor(layoutParent);
937
+ this.yogaNode = createLayoutSlotYogaNode(this.yogaNodeConstructor);
938
+ this.yogaNode.setDisplay(Yoga.Display.None);
939
+ }
940
+ getLayoutNode() {
941
+ return this.yogaNode;
942
+ }
943
+ updateFromLayout() {}
944
+ updateLayout() {}
945
+ onRemove() {}
946
+ isCompatibleWith(layoutParent) {
947
+ return this.yogaNodeConstructor === getLayoutNodeConstructor(layoutParent);
948
+ }
949
+ detachFromSlot() {
950
+ this.slotParent = undefined;
951
+ }
952
+ freeYogaNode() {
953
+ if (this.yogaNodeFreed) {
954
+ return;
955
+ }
956
+ this.yogaNodeFreed = true;
957
+ try {
958
+ this.yogaNode.free();
959
+ } catch {}
960
+ }
961
+ disposeWithoutSlotCascade() {
962
+ if (this.destroyed) {
963
+ return;
964
+ }
965
+ this.destroyed = true;
966
+ this.detachFromSlot();
967
+ this.freeYogaNode();
968
+ }
969
+ destroy() {
970
+ if (this.destroyed) {
971
+ return;
972
+ }
973
+ this.destroyed = true;
974
+ const slotParent = this.slotParent;
975
+ this.slotParent = undefined;
976
+ this.freeYogaNode();
977
+ slotParent?.destroy();
978
+ }
979
+ }
980
+
981
+ class SlotRenderable extends SlotBaseRenderable {
982
+ destroyed = false;
983
+ layoutNodesByParent = new Map;
984
+ textNodesByParent = new Map;
985
+ layoutNodeCount = 0;
986
+ textNodeCount = 0;
987
+ constructor(id) {
988
+ super(id);
989
+ this._visible = false;
990
+ }
991
+ get layoutNode() {
992
+ return this.getCurrentSlotChild(this.layoutNodesByParent);
993
+ }
994
+ get textNode() {
995
+ return this.getCurrentSlotChild(this.textNodesByParent);
996
+ }
997
+ isTextSlotParent(parent) {
998
+ return isTextNodeRenderable2(parent) || parent instanceof TextRenderable3;
999
+ }
1000
+ getCurrentSlotChild(nodesByParent) {
1001
+ for (const node of nodesByParent.values()) {
1002
+ if (node.parent) {
1003
+ return node;
1004
+ }
1005
+ }
1006
+ return nodesByParent.values().next().value;
1007
+ }
1008
+ getTextNodeForParent(parent) {
1009
+ const mappedNode = this.textNodesByParent.get(parent);
1010
+ if (mappedNode) {
1011
+ return mappedNode;
1012
+ }
1013
+ for (const [mappedParent, textNode] of this.textNodesByParent) {
1014
+ if (textNode.parent !== parent) {
1015
+ continue;
1016
+ }
1017
+ this.textNodesByParent.delete(mappedParent);
1018
+ this.textNodesByParent.set(parent, textNode);
1019
+ return textNode;
1020
+ }
1021
+ }
1022
+ getLayoutNodeForParent(parent) {
1023
+ const mappedNode = this.layoutNodesByParent.get(parent);
1024
+ if (mappedNode) {
1025
+ return mappedNode;
1026
+ }
1027
+ for (const [mappedParent, layoutNode] of this.layoutNodesByParent) {
1028
+ if (layoutNode.parent !== parent) {
1029
+ continue;
1030
+ }
1031
+ this.layoutNodesByParent.delete(mappedParent);
1032
+ this.layoutNodesByParent.set(parent, layoutNode);
1033
+ return layoutNode;
1034
+ }
1035
+ }
1036
+ takeReusableTextNode(parent) {
1037
+ for (const [mappedParent, textNode] of this.textNodesByParent) {
1038
+ if (textNode.parent) {
1039
+ continue;
1040
+ }
1041
+ this.textNodesByParent.delete(mappedParent);
1042
+ this.textNodesByParent.set(parent, textNode);
1043
+ return textNode;
1044
+ }
1045
+ }
1046
+ takeReusableLayoutNode(parent) {
1047
+ for (const [mappedParent, layoutNode] of this.layoutNodesByParent) {
1048
+ if (layoutNode.parent) {
1049
+ continue;
1050
+ }
1051
+ if (!layoutNode.isCompatibleWith(parent)) {
1052
+ continue;
1053
+ }
1054
+ this.layoutNodesByParent.delete(mappedParent);
1055
+ this.layoutNodesByParent.set(parent, layoutNode);
1056
+ return layoutNode;
1057
+ }
1058
+ }
1059
+ disposeDetachedTextNodes() {
1060
+ for (const [parent, textNode] of this.textNodesByParent) {
1061
+ if (textNode.parent) {
1062
+ continue;
1063
+ }
1064
+ this.textNodesByParent.delete(parent);
1065
+ textNode.disposeWithoutSlotCascade();
1066
+ }
1067
+ }
1068
+ disposeDetachedIncompatibleLayoutNodes(parent) {
1069
+ for (const [mappedParent, layoutNode] of this.layoutNodesByParent) {
1070
+ if (layoutNode.parent || layoutNode.isCompatibleWith(parent)) {
1071
+ continue;
1072
+ }
1073
+ this.layoutNodesByParent.delete(mappedParent);
1074
+ layoutNode.disposeWithoutSlotCascade();
1075
+ }
1076
+ }
1077
+ getAttachedSlotParent(excludedNode) {
1078
+ for (const textNode of this.textNodesByParent.values()) {
1079
+ if (textNode !== excludedNode && textNode.parent) {
1080
+ return textNode.parent;
1081
+ }
1082
+ }
1083
+ for (const layoutNode of this.layoutNodesByParent.values()) {
1084
+ if (layoutNode !== excludedNode && layoutNode.parent) {
1085
+ return layoutNode.parent;
1086
+ }
1087
+ }
1088
+ return null;
1089
+ }
1090
+ hasOtherAttachedSlotChildren(excludedNode) {
1091
+ return this.getAttachedSlotParent(excludedNode) !== null;
1092
+ }
1093
+ getSlotChild(parent) {
1094
+ if (this.isTextSlotParent(parent)) {
1095
+ const existingTextNode = this.getTextNodeForParent(parent);
1096
+ if (existingTextNode) {
1097
+ return existingTextNode;
1098
+ }
1099
+ const reusableTextNode = this.takeReusableTextNode(parent);
1100
+ if (reusableTextNode) {
1101
+ return reusableTextNode;
1102
+ }
1103
+ this.disposeDetachedIncompatibleLayoutNodes(parent);
1104
+ const textNode = new TextSlotRenderable(`slot-text-${this.id}-${++this.textNodeCount}`, this);
1105
+ this.textNodesByParent.set(parent, textNode);
1106
+ return textNode;
1107
+ }
1108
+ const existingLayoutNode = this.getLayoutNodeForParent(parent);
1109
+ if (existingLayoutNode) {
1110
+ return existingLayoutNode;
1111
+ }
1112
+ const reusableLayoutNode = this.takeReusableLayoutNode(parent);
1113
+ if (reusableLayoutNode) {
1114
+ return reusableLayoutNode;
1115
+ }
1116
+ this.disposeDetachedTextNodes();
1117
+ this.disposeDetachedIncompatibleLayoutNodes(parent);
1118
+ const layoutNode = new LayoutSlotRenderable(`slot-layout-${this.id}-${++this.layoutNodeCount}`, this, parent);
1119
+ this.layoutNodesByParent.set(parent, layoutNode);
1120
+ return layoutNode;
1121
+ }
1122
+ getSlotChildForRemoval(parent) {
1123
+ if (this.isTextSlotParent(parent)) {
1124
+ return this.getTextNodeForParent(parent);
1125
+ }
1126
+ return this.getLayoutNodeForParent(parent);
1127
+ }
1128
+ didRemoveSlotChild(parent, child) {
1129
+ const hasOtherAttachedSlotChildren = this.hasOtherAttachedSlotChildren(child);
1130
+ if (hasOtherAttachedSlotChildren && child instanceof TextSlotRenderable && this.getTextNodeForParent(parent) === child) {
1131
+ this.textNodesByParent.delete(parent);
1132
+ child.disposeWithoutSlotCascade();
1133
+ }
1134
+ if (hasOtherAttachedSlotChildren && child instanceof LayoutSlotRenderable && this.getLayoutNodeForParent(parent) === child) {
1135
+ this.layoutNodesByParent.delete(parent);
1136
+ child.disposeWithoutSlotCascade();
1137
+ }
1138
+ if (this.parent === parent) {
1139
+ this.parent = this.getAttachedSlotParent(child);
1140
+ }
1141
+ }
1142
+ destroy() {
1143
+ if (this.destroyed) {
1144
+ return;
1145
+ }
1146
+ this.destroyed = true;
1147
+ const layoutNodes = new Set(this.layoutNodesByParent.values());
1148
+ this.layoutNodesByParent.clear();
1149
+ for (const layoutNode of layoutNodes) {
1150
+ layoutNode.destroy();
1151
+ }
1152
+ const textNodes = new Set(this.textNodesByParent.values());
1153
+ this.textNodesByParent.clear();
1154
+ for (const textNode of textNodes) {
1155
+ textNode.destroy();
1156
+ }
1157
+ }
1158
+ }
1159
+ // src/scrollback.ts
1160
+ import {
1161
+ BoxRenderable as BoxRenderable2,
1162
+ RootRenderable
1163
+ } from "@opentui/core";
1164
+ import { createSignal as createSignal2 } from "solid-js";
1165
+ var solidScrollbackRootCounter = 0;
1166
+ var MAX_AUTO_HEIGHT_PASSES = 4;
1167
+ function normalizeSnapshotDimension(value, axis) {
1168
+ if (value === undefined) {
1169
+ return;
1170
+ }
1171
+ if (!Number.isFinite(value)) {
1172
+ throw new Error(`createScrollbackWriter requires a finite ${axis}`);
1173
+ }
1174
+ return Math.max(1, Math.trunc(value));
1175
+ }
1176
+ function createSnapshotRendererValue(renderContext, root, width, height, firstLineOffset) {
1177
+ const [snapshotWidth] = createSignal2(width);
1178
+ const [snapshotHeight, setSnapshotHeight] = createSignal2(height);
1179
+ const renderer = Object.create(renderContext);
1180
+ let offset = firstLineOffset;
1181
+ Object.defineProperties(renderer, {
1182
+ root: {
1183
+ value: root,
1184
+ enumerable: true,
1185
+ configurable: true
1186
+ },
1187
+ width: {
1188
+ get: snapshotWidth,
1189
+ enumerable: true,
1190
+ configurable: true
1191
+ },
1192
+ height: {
1193
+ get: snapshotHeight,
1194
+ enumerable: true,
1195
+ configurable: true
1196
+ },
1197
+ claimFirstLineOffset: {
1198
+ value: () => {
1199
+ const out = offset;
1200
+ offset = 0;
1201
+ return out;
1202
+ },
1203
+ enumerable: true,
1204
+ configurable: true
1205
+ }
1206
+ });
1207
+ return {
1208
+ renderer,
1209
+ getHeight: snapshotHeight,
1210
+ setHeight(nextHeight) {
1211
+ setSnapshotHeight(nextHeight);
1212
+ renderer.emit("resize", snapshotWidth(), nextHeight);
1213
+ }
1214
+ };
1215
+ }
1216
+ function runLifecyclePasses(renderContext) {
1217
+ for (const renderable of renderContext.getLifecyclePasses()) {
1218
+ renderable.onLifecyclePass?.call(renderable);
1219
+ }
1220
+ }
1221
+ function clearLifecyclePasses(renderContext) {
1222
+ for (const renderable of [...renderContext.getLifecyclePasses()]) {
1223
+ renderContext.unregisterLifecyclePass(renderable);
1224
+ }
1225
+ }
1226
+ function measureSnapshotHeight(renderContext, root) {
1227
+ const measureRoot = new RootRenderable(renderContext);
1228
+ try {
1229
+ measureRoot.add(root);
1230
+ runLifecyclePasses(renderContext);
1231
+ measureRoot.calculateLayout();
1232
+ return Math.max(1, Math.trunc(root.getLayoutNode().getComputedLayout().height));
1233
+ } finally {
1234
+ if (root.parent === measureRoot) {
1235
+ measureRoot.remove(root.id);
1236
+ }
1237
+ measureRoot.destroyRecursively();
1238
+ }
1239
+ }
1240
+ function resolveSnapshotHeight(renderContext, root, snapshotRenderer) {
1241
+ for (let pass = 0;pass < MAX_AUTO_HEIGHT_PASSES; pass++) {
1242
+ const measuredHeight = measureSnapshotHeight(renderContext, root);
1243
+ if (measuredHeight === snapshotRenderer.getHeight()) {
1244
+ clearLifecyclePasses(renderContext);
1245
+ return measuredHeight;
1246
+ }
1247
+ snapshotRenderer.setHeight(measuredHeight);
1248
+ }
1249
+ return measureSnapshotHeight(renderContext, root);
1250
+ }
1251
+ function createScrollbackWriter(node, options = {}) {
1252
+ return (ctx) => {
1253
+ const width = normalizeSnapshotDimension(options.width, "width") ?? Math.max(1, Math.trunc(ctx.width));
1254
+ const height = normalizeSnapshotDimension(options.height, "height");
1255
+ const startOnNewLine = options.startOnNewLine ?? true;
1256
+ const firstLineWidth = !startOnNewLine && ctx.tailColumn > 0 && ctx.tailColumn < ctx.width ? Math.min(width, ctx.width - ctx.tailColumn) : width;
1257
+ const firstLineOffset = width - firstLineWidth;
1258
+ const root = new BoxRenderable2(ctx.renderContext, {
1259
+ id: `solid-scrollback-root-${solidScrollbackRootCounter++}`,
1260
+ position: "absolute",
1261
+ left: 0,
1262
+ top: 0,
1263
+ width,
1264
+ height: height ?? "auto",
1265
+ border: false,
1266
+ backgroundColor: "transparent",
1267
+ shouldFill: false,
1268
+ flexDirection: "column"
1269
+ });
1270
+ const snapshotRenderer = createSnapshotRendererValue(ctx.renderContext, root, width, height ?? Math.max(1, ctx.renderContext.height), firstLineOffset);
1271
+ let dispose;
1272
+ let disposed = false;
1273
+ const teardown = () => {
1274
+ if (disposed) {
1275
+ return;
1276
+ }
1277
+ disposed = true;
1278
+ dispose?.();
1279
+ };
1280
+ try {
1281
+ dispose = _render(() => createComponent2(RendererContext.Provider, {
1282
+ get value() {
1283
+ return snapshotRenderer.renderer;
1284
+ },
1285
+ get children() {
1286
+ return node(ctx);
1287
+ }
1288
+ }), root);
1289
+ return {
1290
+ root,
1291
+ width,
1292
+ height: height ?? resolveSnapshotHeight(ctx.renderContext, root, snapshotRenderer),
1293
+ rowColumns: options.rowColumns,
1294
+ startOnNewLine,
1295
+ trailingNewline: options.trailingNewline,
1296
+ teardown
1297
+ };
1298
+ } catch (error) {
1299
+ teardown();
1300
+ root.destroyRecursively();
1301
+ throw error;
1302
+ }
1303
+ };
1304
+ }
1305
+ function writeSolidToScrollback(renderer, node, options = {}) {
1306
+ renderer.writeToScrollback(createScrollbackWriter(node, options));
1307
+ }
1308
+ // src/time-to-first-draw.tsx
1309
+ import { TimeToFirstDrawRenderable } from "@opentui/core";
1310
+ extend({
1311
+ time_to_first_draw: TimeToFirstDrawRenderable
1312
+ });
1313
+ var TimeToFirstDraw = (props) => {
1314
+ return (() => {
1315
+ var _el$ = createElement("time_to_first_draw");
1316
+ spread(_el$, props, false);
1317
+ return _el$;
1318
+ })();
1319
+ };
1320
+ // src/plugins/slot.tsx
1321
+ import { createSlotRegistry } from "@opentui/core";
1322
+ import { children, createMemo as createMemo3, createSignal as createSignal3, ErrorBoundary, For, onCleanup as onCleanup3, splitProps as splitProps2 } from "solid-js";
1323
+ var EMPTY_ENTRY_IDS = [];
1324
+ function createSolidSlotRegistry(renderer, context, options = {}) {
1325
+ return createSlotRegistry(renderer, "solid:slot-registry", context, options);
1326
+ }
1327
+ function createSlot(registry, options = {}) {
1328
+ return function BoundSlot(props) {
1329
+ return createComponent2(Slot, mergeProps3(props, {
1330
+ registry,
1331
+ get pluginFailurePlaceholder() {
1332
+ return options.pluginFailurePlaceholder;
1333
+ }
1334
+ }));
1335
+ };
1336
+ }
1337
+ function Slot(props) {
1338
+ const [local, slotProps] = splitProps2(props, ["registry", "name", "mode", "children", "pluginFailurePlaceholder"]);
1339
+ const registry = () => local.registry;
1340
+ const pluginFailurePlaceholder = () => local.pluginFailurePlaceholder;
1341
+ const [version, setVersion] = createSignal3(0);
1342
+ let queued = false;
1343
+ let disposed = false;
1344
+ const unsubscribe = registry().subscribe(() => {
1345
+ if (queued)
1346
+ return;
1347
+ queued = true;
1348
+ setVersion((current) => current + 1);
1349
+ queueMicrotask(() => {
1350
+ queued = false;
1351
+ if (disposed)
1352
+ return;
1353
+ });
1354
+ });
1355
+ onCleanup3(() => {
1356
+ disposed = true;
1357
+ unsubscribe();
1358
+ });
1359
+ const entries = createMemo3((previousEntries = []) => {
1360
+ version();
1361
+ const resolvedEntries = registry().resolveEntries(local.name);
1362
+ if (resolvedEntries.length === 0) {
1363
+ if (previousEntries.length === 0)
1364
+ return previousEntries;
1365
+ return [];
1366
+ }
1367
+ const previousById = new Map(previousEntries.map((entry) => [entry.id, entry]));
1368
+ const nextEntries = resolvedEntries.map((entry) => {
1369
+ const previousEntry = previousById.get(entry.id);
1370
+ if (previousEntry && previousEntry.renderer === entry.renderer) {
1371
+ return previousEntry;
1372
+ }
1373
+ return entry;
1374
+ });
1375
+ const unchanged = nextEntries.length === previousEntries.length && nextEntries.every((entry, index) => entry === previousEntries[index]);
1376
+ if (unchanged)
1377
+ return previousEntries;
1378
+ return nextEntries;
1379
+ });
1380
+ const entryIds = createMemo3(() => entries().map((entry) => entry.id));
1381
+ const entriesById = createMemo3(() => new Map(entries().map((entry) => [entry.id, entry])));
1382
+ const slotName = () => String(local.name);
1383
+ const renderFallback = () => {
1384
+ const value = children(() => local.children)();
1385
+ return value ?? null;
1386
+ };
1387
+ const resolveFallback = (fallbackValue) => fallbackValue?.() ?? null;
1388
+ const renderPluginFailurePlaceholder = (failure, fallbackValue) => {
1389
+ if (!pluginFailurePlaceholder()) {
1390
+ return resolveFallback(fallbackValue);
1391
+ }
1392
+ try {
1393
+ return pluginFailurePlaceholder()(failure);
1394
+ } catch (error) {
1395
+ registry().reportPluginError({
1396
+ pluginId: failure.pluginId,
1397
+ slot: failure.slot ?? slotName(),
1398
+ phase: "error_placeholder",
1399
+ source: "solid",
1400
+ error
1401
+ });
1402
+ return resolveFallback(fallbackValue);
1403
+ }
1404
+ };
1405
+ const renderEntry = (entry, fallbackOnError) => {
1406
+ let initialRender;
1407
+ try {
1408
+ initialRender = entry.renderer(registry().context, slotProps);
1409
+ } catch (error) {
1410
+ const failure = registry().reportPluginError({
1411
+ pluginId: entry.id,
1412
+ slot: slotName(),
1413
+ phase: "render",
1414
+ source: "solid",
1415
+ error
1416
+ });
1417
+ return renderPluginFailurePlaceholder(failure, fallbackOnError);
1418
+ }
1419
+ const resolvedInitialRender = children(() => initialRender);
1420
+ const hasInitialOutput = resolvedInitialRender.toArray().some((node) => node !== null && node !== undefined && node !== false);
1421
+ if (!hasInitialOutput) {
1422
+ return resolveFallback(fallbackOnError);
1423
+ }
1424
+ return createComponent2(ErrorBoundary, {
1425
+ fallback: (error) => {
1426
+ const failure = registry().reportPluginError({
1427
+ pluginId: entry.id,
1428
+ slot: slotName(),
1429
+ phase: "render",
1430
+ source: "solid",
1431
+ error
1432
+ });
1433
+ return renderPluginFailurePlaceholder(failure, fallbackOnError);
1434
+ },
1435
+ get children() {
1436
+ return resolvedInitialRender();
1437
+ }
1438
+ });
1439
+ };
1440
+ const AppendEntry = (appendProps) => {
1441
+ const entry = createMemo3(() => entriesById().get(appendProps.entryId));
1442
+ return memo2(() => {
1443
+ const resolvedEntry = entry();
1444
+ if (!resolvedEntry) {
1445
+ return null;
1446
+ }
1447
+ return renderEntry(resolvedEntry);
1448
+ });
1449
+ };
1450
+ const appendEntryIds = createMemo3(() => {
1451
+ const mode = local.mode ?? "append";
1452
+ if (mode !== "append") {
1453
+ return EMPTY_ENTRY_IDS;
1454
+ }
1455
+ return entryIds();
1456
+ });
1457
+ const appendView = [renderFallback, createComponent2(For, {
1458
+ get each() {
1459
+ return appendEntryIds();
1460
+ },
1461
+ children: (entryId) => createComponent2(AppendEntry, {
1462
+ entryId
1463
+ })
1464
+ })];
1465
+ return memo2(() => {
1466
+ const resolvedEntries = entries();
1467
+ const mode = local.mode ?? "append";
1468
+ if (resolvedEntries.length === 0) {
1469
+ return renderFallback();
1470
+ }
1471
+ if (mode === "single_winner") {
1472
+ const winner = resolvedEntries[0];
1473
+ if (!winner) {
1474
+ return renderFallback();
1475
+ }
1476
+ return renderEntry(winner, renderFallback);
1477
+ }
1478
+ if (mode === "replace") {
1479
+ const renderedEntries = resolvedEntries.map((entry) => renderEntry(entry));
1480
+ const hasPluginOutput = renderedEntries.some((entry) => entry !== null && entry !== undefined && entry !== false);
1481
+ if (!hasPluginOutput) {
1482
+ return renderFallback();
1483
+ }
1484
+ return renderedEntries;
1485
+ }
1486
+ return appendView;
1487
+ });
1488
+ }
1489
+
1490
+ // index.ts
1491
+ var mountSolidRoot = (renderer, node) => {
1492
+ let dispose;
1493
+ let disposeRequested = false;
1494
+ let disposed = false;
1495
+ let mounting = true;
1496
+ let destroyRequested = false;
1497
+ const originalDestroy = renderer.destroy.bind(renderer);
1498
+ const runDispose = () => {
1499
+ if (disposed) {
1500
+ return;
1501
+ }
1502
+ if (!dispose) {
1503
+ disposeRequested = true;
1504
+ return;
1505
+ }
1506
+ disposed = true;
1507
+ dispose();
1508
+ };
1509
+ renderer.once("destroy", runDispose);
1510
+ renderer.destroy = () => {
1511
+ if (mounting) {
1512
+ destroyRequested = true;
1513
+ return;
1514
+ }
1515
+ originalDestroy();
1516
+ };
1517
+ try {
1518
+ dispose = _render(() => createComponent2(RendererContext.Provider, {
1519
+ get value() {
1520
+ return renderer;
1521
+ },
1522
+ get children() {
1523
+ return createComponent2(node, {});
1524
+ }
1525
+ }), renderer.root);
1526
+ } finally {
1527
+ mounting = false;
1528
+ renderer.destroy = originalDestroy;
1529
+ }
1530
+ if (disposeRequested) {
1531
+ runDispose();
1532
+ }
1533
+ if (destroyRequested) {
1534
+ originalDestroy();
1535
+ }
1536
+ };
1537
+ var render = async (node, rendererOrConfig = {}) => {
1538
+ const renderer = rendererOrConfig instanceof CliRenderer ? rendererOrConfig : await createCliRenderer({
1539
+ ...rendererOrConfig,
1540
+ onDestroy: () => {
1541
+ rendererOrConfig.onDestroy?.();
1542
+ }
1543
+ });
1544
+ engine2.attach(renderer);
1545
+ mountSolidRoot(renderer, node);
1546
+ };
1547
+ var testRender = async (node, renderConfig = {}) => {
1548
+ const testSetup = await createTestRenderer({
1549
+ ...renderConfig,
1550
+ onDestroy: () => {
1551
+ renderConfig.onDestroy?.();
1552
+ }
1553
+ });
1554
+ engine2.attach(testSetup.renderer);
1555
+ mountSolidRoot(testSetup.renderer, node);
1556
+ return testSetup;
1557
+ };
1558
+ export {
1559
+ writeSolidToScrollback,
1560
+ useTimeline,
1561
+ useTerminalDimensions,
1562
+ useSelectionHandler,
1563
+ useRenderer,
1564
+ usePaste,
1565
+ useKeyboard,
1566
+ useKeyHandler,
1567
+ use,
1568
+ textNodeKeys,
1569
+ testRender,
1570
+ spread,
1571
+ setProp,
1572
+ render,
1573
+ onResize,
1574
+ onFocus,
1575
+ onBlur,
1576
+ mergeProps3 as mergeProps,
1577
+ memo2 as memo,
1578
+ insertNode,
1579
+ insert,
1580
+ getComponentCatalogue,
1581
+ extend,
1582
+ effect,
1583
+ createTextNode,
1584
+ createSolidSlotRegistry,
1585
+ createSlotNode,
1586
+ createSlot,
1587
+ createScrollbackWriter,
1588
+ createElement,
1589
+ createDynamic,
1590
+ createComponent2 as createComponent,
1591
+ componentCatalogue,
1592
+ baseComponents,
1593
+ _render,
1594
+ UnderlineSpanRenderable,
1595
+ TimeToFirstDraw,
1596
+ TextSlotRenderable,
1597
+ SlotRenderable,
1598
+ Slot,
1599
+ RendererContext,
1600
+ Portal,
1601
+ LinkRenderable,
1602
+ LineBreakRenderable,
1603
+ LayoutSlotRenderable,
1604
+ ItalicSpanRenderable,
1605
+ Dynamic,
1606
+ BoldSpanRenderable
1607
+ };
1608
+
1609
+ //# debugId=E514C995048B172A64756E2164756E21