@opentui/solid 0.5.16 → 0.6.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.
package/README.md CHANGED
@@ -87,7 +87,7 @@ OpenTUI Solid exposes intrinsic JSX elements that map to OpenTUI renderables:
87
87
 
88
88
  ### `render(node, rendererOrConfig?)`
89
89
 
90
- Render a Solid component tree into a CLI renderer. If `rendererOrConfig` is omitted, a renderer is created with default options.
90
+ Render a Solid component tree into a CLI renderer. If you omit `rendererOrConfig`, `render()` creates a renderer with default options. `render()` returns a promise that resolves after the initial mount. Destroying the renderer disposes the Solid root.
91
91
 
92
92
  ```tsx
93
93
  import { render } from "@opentui/solid"
@@ -120,6 +120,9 @@ import { extend } from "@opentui/solid"
120
120
  extend({ customBox: CustomBoxRenderable })
121
121
  ```
122
122
 
123
+ Solid calls the constructor with `{ id }` only. After construction, Solid applies each JSX prop to the instance. A class
124
+ that reads a value only from its constructor options does not get that value from JSX.
125
+
123
126
  ### `getComponentCatalogue()`
124
127
 
125
128
  Returns the current component catalogue that powers JSX tag lookup.
@@ -138,7 +141,7 @@ Returns the current component catalogue that powers JSX tag lookup.
138
141
 
139
142
  ### `Portal`
140
143
 
141
- Render children into a different mount node, useful for overlays and tooltips.
144
+ Render children into a different mount node. Use it for overlays and tooltips.
142
145
 
143
146
  ```tsx
144
147
  import { Portal } from "@opentui/solid"
@@ -165,7 +168,7 @@ import { Dynamic } from "@opentui/solid"
165
168
  - `scrollbox`: scrollable container
166
169
  - `ascii_font`: ASCII art text renderer
167
170
 
168
- QR code support is available from `@opentui/qrcode/solid` and must be registered explicitly with `registerQRCode()`.
171
+ For QR codes, call `registerQRCode()` from `@opentui/qrcode/solid`. It registers the `qr_code` element.
169
172
 
170
173
  ### Input
171
174
 
@@ -182,7 +185,7 @@ QR code support is available from `@opentui/qrcode/solid` and must be registered
182
185
 
183
186
  ### Text Modifiers
184
187
 
185
- These must appear inside a `text` component:
188
+ Use these only inside a `text` component:
186
189
 
187
190
  - `span`: inline styled text
188
191
  - `strong`/`b`: bold text
package/index.bun.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  // index.ts
3
- import { CliRenderer, createCliRenderer, engine as engine2 } from "@opentui/core";
3
+ import { CliRenderer, createCliRenderer, engine } from "@opentui/core";
4
4
  import { createTestRenderer } from "@opentui/core/testing";
5
5
 
6
6
  // src/elements/catalogue.ts
@@ -114,7 +114,7 @@ function getComponentCatalogue() {
114
114
  }
115
115
  // src/elements/hooks.ts
116
116
  import {
117
- engine,
117
+ getTimelineEngine,
118
118
  Timeline
119
119
  } from "@opentui/core";
120
120
  import { createContext, createSignal, onCleanup, onMount, useContext } from "solid-js";
@@ -199,6 +199,7 @@ var useSelectionHandler = (callback) => {
199
199
  });
200
200
  };
201
201
  var useTimeline = (options = {}) => {
202
+ const engine = getTimelineEngine(useRenderer());
202
203
  const timeline = new Timeline(options);
203
204
  onMount(() => {
204
205
  if (options.autoplay !== false) {
@@ -207,12 +208,16 @@ var useTimeline = (options = {}) => {
207
208
  engine.register(timeline);
208
209
  });
209
210
  onCleanup(() => {
210
- timeline.pause();
211
- engine.unregister(timeline);
211
+ try {
212
+ timeline.pause();
213
+ } finally {
214
+ engine.unregister(timeline);
215
+ }
212
216
  });
213
217
  return timeline;
214
218
  };
215
219
  // src/elements/extras.ts
220
+ import { Renderable as Renderable2 } from "@opentui/core";
216
221
  import { createEffect, createMemo as createMemo2, getOwner, onCleanup as onCleanup3, runWithOwner, splitProps, untrack as untrack2 } from "solid-js";
217
222
 
218
223
  // src/reconciler.ts
@@ -224,7 +229,6 @@ import {
224
229
  InputRenderableEvents,
225
230
  isTextNodeRenderable,
226
231
  isEditBufferRenderable,
227
- parseColor,
228
232
  Renderable,
229
233
  RootTextNodeRenderable,
230
234
  ScrollBoxRenderable as ScrollBoxRenderable2,
@@ -233,10 +237,11 @@ import {
233
237
  TabSelectRenderable as TabSelectRenderable2,
234
238
  TabSelectRenderableEvents,
235
239
  TextNodeRenderable as TextNodeRenderable2,
236
- TextRenderable as TextRenderable2
240
+ TextRenderable as TextRenderable2,
241
+ TextTableRenderable
237
242
  } from "@opentui/core";
238
243
  import { decodeHTMLStrict } from "entities";
239
- import { onCleanup as onCleanup2, useContext as useContext2 } from "solid-js";
244
+ import { createContext as createContext2, onCleanup as onCleanup2, useContext as useContext2 } from "solid-js";
240
245
 
241
246
  // src/renderer/universal.js
242
247
  import { createRoot, createRenderEffect, createMemo, createComponent, untrack, mergeProps } from "solid-js";
@@ -532,6 +537,7 @@ class TextNode extends TextNodeRenderable2 {
532
537
  return node;
533
538
  }
534
539
  }
540
+ var RenderableContext = createContext2();
535
541
  var logId = (node) => {
536
542
  if (!node)
537
543
  return;
@@ -626,7 +632,7 @@ function _getParentNode(childNode) {
626
632
  return parent;
627
633
  }
628
634
  var {
629
- render: _render,
635
+ render: renderRoot,
630
636
  effect,
631
637
  memo: memo2,
632
638
  createComponent: createComponent2,
@@ -642,7 +648,7 @@ var {
642
648
  createElement(tagName) {
643
649
  log("Creating element:", tagName);
644
650
  const id = getNextId(tagName);
645
- const solidRenderer = useContext2(RendererContext);
651
+ const solidRenderer = useContext2(RenderableContext)?.() ?? useContext2(RendererContext);
646
652
  if (!solidRenderer) {
647
653
  throw new Error("No renderer found");
648
654
  }
@@ -685,9 +691,9 @@ var {
685
691
  return;
686
692
  }
687
693
  if (name === "style") {
688
- node.attributes |= createTextAttributes(value);
689
- node.fg = value.fg ? parseColor(value.fg) : node.fg;
690
- node.bg = value.bg ? parseColor(value.bg) : node.bg;
694
+ node.attributes = node.attributes & ~createTextAttributes(prev) | createTextAttributes(value);
695
+ node.fg = value?.fg;
696
+ node.bg = value?.bg;
691
697
  return;
692
698
  }
693
699
  return;
@@ -787,7 +793,11 @@ var {
787
793
  break;
788
794
  case "text":
789
795
  case "content": {
790
- const textValue = typeof value === "string" ? value : Array.isArray(value) ? value.join("") : `${value}`;
796
+ if (name === "content" && node instanceof TextTableRenderable) {
797
+ node.content = value;
798
+ break;
799
+ }
800
+ const textValue = typeof value === "string" ? value : Array.isArray(value) ? value.join("") : `${value ?? ""}`;
791
801
  node[name] = textValue;
792
802
  break;
793
803
  }
@@ -839,33 +849,63 @@ var {
839
849
  return nextSibling;
840
850
  }
841
851
  });
852
+ function _render(code, root) {
853
+ return renderRoot(() => RenderableContext.Provider({
854
+ value: root instanceof Renderable ? () => root.ctx : undefined,
855
+ get children() {
856
+ return code();
857
+ }
858
+ }), root);
859
+ }
842
860
 
843
861
  // src/elements/extras.ts
844
862
  function Portal(props) {
845
863
  const renderer = useRenderer();
846
- const marker = createSlotNode(), mount = () => props.mount || renderer.root, owner = getOwner();
864
+ const marker = createSlotNode(), owner = getOwner();
847
865
  let content;
866
+ let container;
848
867
  createEffect(() => {
849
- content || (content = runWithOwner(owner, () => createMemo2(() => props.children)));
850
- const el = mount();
851
- const container = createElement("box"), renderRoot = container;
852
- Object.defineProperty(container, "_$host", {
853
- get() {
854
- return marker.parent;
855
- },
856
- configurable: true
868
+ const mount = createMemo2(() => {
869
+ const el = props.mount || renderer.root;
870
+ const scene = el instanceof Renderable2 ? el.ctx.nativeScene : renderer.nativeScene;
871
+ const currentScene = container instanceof Renderable2 ? container.ctx.nativeScene : renderer.nativeScene;
872
+ if (container && scene !== currentScene && container.getChildrenCount() !== 0) {
873
+ throw new Error("Cannot retarget a Portal with existing nodes between native scenes");
874
+ }
875
+ return el;
857
876
  });
858
- insert(renderRoot, content);
859
- el.add(container);
860
- props.ref && props.ref(container);
861
- onCleanup3(() => {
862
- el.remove(container);
863
- process.nextTick(() => {
864
- if (!container.parent) {
865
- container.destroyRecursively();
877
+ const context = () => {
878
+ const el = untrack2(mount);
879
+ return el instanceof Renderable2 && el.ctx.nativeScene !== renderer.nativeScene ? el.ctx : renderer;
880
+ };
881
+ createEffect(() => {
882
+ const el = mount();
883
+ content ||= runWithOwner(owner, () => RenderableContext.Provider({
884
+ value: context,
885
+ get children() {
886
+ return props.children;
887
+ }
888
+ }));
889
+ let nextContainer;
890
+ RenderableContext.Provider({
891
+ value: context,
892
+ get children() {
893
+ nextContainer = createElement("box");
894
+ return;
866
895
  }
867
896
  });
868
- });
897
+ Object.defineProperty(nextContainer, "_$host", {
898
+ get() {
899
+ return marker.parent;
900
+ },
901
+ configurable: true
902
+ });
903
+ insert(nextContainer, content);
904
+ el.add(nextContainer);
905
+ container = nextContainer;
906
+ onCleanup3(() => _removeNode(el, nextContainer));
907
+ props.ref && props.ref(nextContainer);
908
+ }, undefined, { render: true });
869
909
  }, undefined, { render: true });
870
910
  return marker;
871
911
  }
@@ -890,14 +930,7 @@ function Dynamic(props) {
890
930
  return createDynamic(() => props.component, others);
891
931
  }
892
932
  // src/elements/slot.ts
893
- import { BaseRenderable as BaseRenderable2, isTextNodeRenderable as isTextNodeRenderable2, TextNodeRenderable as TextNodeRenderable3, TextRenderable as TextRenderable3, Yoga } from "@opentui/core";
894
- function getLayoutNodeConstructor(parent) {
895
- const parentLayoutNode = parent?.getLayoutNode?.();
896
- return parentLayoutNode?.constructor;
897
- }
898
- function createLayoutSlotYogaNode(parentNodeConstructor) {
899
- return parentNodeConstructor?.create?.() ?? Yoga.default.Node.create();
900
- }
933
+ import { BaseRenderable as BaseRenderable2, isTextNodeRenderable as isTextNodeRenderable2, Renderable as Renderable3, TextNodeRenderable as TextNodeRenderable3, TextRenderable as TextRenderable3 } from "@opentui/core";
901
934
 
902
935
  class SlotBaseRenderable extends BaseRenderable2 {
903
936
  constructor(id) {
@@ -954,64 +987,29 @@ class TextSlotRenderable extends TextNodeRenderable3 {
954
987
  this.slotParent = undefined;
955
988
  this.parent?.remove(this);
956
989
  slotParent?.didDestroySlotChild(this);
990
+ super.destroy();
991
+ }
992
+ destroyRecursively() {
993
+ this.destroy();
957
994
  }
958
995
  }
959
996
 
960
- class LayoutSlotRenderable extends SlotBaseRenderable {
961
- yogaNode;
997
+ class LayoutSlotRenderable extends Renderable3 {
962
998
  slotParent;
963
- destroyed = false;
964
- yogaNodeConstructor;
965
- yogaNodeFreed = false;
966
999
  constructor(id, parent, layoutParent) {
967
- super(id);
968
- this._visible = false;
1000
+ super(layoutParent.ctx, { id, visible: false });
969
1001
  this.slotParent = parent;
970
- this.yogaNodeConstructor = getLayoutNodeConstructor(layoutParent);
971
- this.yogaNode = createLayoutSlotYogaNode(this.yogaNodeConstructor);
972
- this.yogaNode.setDisplay(Yoga.Display.None);
973
1002
  }
974
- getLayoutNode() {
975
- return this.yogaNode;
976
- }
977
- updateFromLayout() {}
978
- updateLayout() {}
979
- onRemove() {}
980
1003
  isCompatibleWith(layoutParent) {
981
- return this.yogaNodeConstructor === getLayoutNodeConstructor(layoutParent);
982
- }
983
- detachFromSlot() {
984
- this.slotParent = undefined;
985
- }
986
- freeYogaNode() {
987
- if (this.yogaNodeFreed) {
988
- return;
989
- }
990
- this.yogaNodeFreed = true;
991
- try {
992
- this.yogaNode.free();
993
- } catch {}
1004
+ return layoutParent instanceof Renderable3 && layoutParent.ctx.nativeScene === this.ctx.nativeScene;
994
1005
  }
995
1006
  disposeWithoutSlotCascade() {
996
- if (this.destroyed) {
997
- return;
998
- }
999
- this.destroyed = true;
1000
- this.detachFromSlot();
1001
- this.freeYogaNode();
1002
- }
1003
- destroyRecursively() {
1007
+ this.slotParent = undefined;
1004
1008
  this.destroy();
1005
1009
  }
1006
- destroy() {
1007
- if (this.destroyed) {
1008
- return;
1009
- }
1010
- this.destroyed = true;
1010
+ destroySelf() {
1011
1011
  const slotParent = this.slotParent;
1012
1012
  this.slotParent = undefined;
1013
- this.parent?.remove(this);
1014
- this.freeYogaNode();
1015
1013
  slotParent?.didDestroySlotChild(this);
1016
1014
  }
1017
1015
  }
@@ -1105,7 +1103,7 @@ class SlotRenderable extends SlotBaseRenderable {
1105
1103
  }
1106
1104
  disposeDetachedIncompatibleLayoutNodes(parent) {
1107
1105
  for (const [mappedParent, layoutNode] of this.layoutNodesByParent) {
1108
- if (layoutNode.parent || layoutNode.isCompatibleWith(parent)) {
1106
+ if (layoutNode.parent || !this.isTextSlotParent(parent) && layoutNode.isCompatibleWith(parent)) {
1109
1107
  continue;
1110
1108
  }
1111
1109
  this.layoutNodesByParent.delete(mappedParent);
@@ -1153,7 +1151,10 @@ class SlotRenderable extends SlotBaseRenderable {
1153
1151
  }
1154
1152
  this.disposeDetachedTextNodes();
1155
1153
  this.disposeDetachedIncompatibleLayoutNodes(parent);
1156
- const layoutNode = new LayoutSlotRenderable(`slot-layout-${this.id}-${++this.layoutNodeCount}`, this, parent);
1154
+ const id = `slot-layout-${this.id}-${++this.layoutNodeCount}`;
1155
+ if (!(parent instanceof Renderable3))
1156
+ throw new Error("Layout slots require a renderable parent");
1157
+ const layoutNode = new LayoutSlotRenderable(id, this, parent);
1157
1158
  this.layoutNodesByParent.set(parent, layoutNode);
1158
1159
  return layoutNode;
1159
1160
  }
@@ -1165,6 +1166,9 @@ class SlotRenderable extends SlotBaseRenderable {
1165
1166
  }
1166
1167
  didRemoveSlotChild(parent, child) {
1167
1168
  const hasOtherAttachedSlotChildren = this.hasOtherAttachedSlotChildren(child);
1169
+ if (this.parent === parent) {
1170
+ this.parent = this.getAttachedSlotParent(child);
1171
+ }
1168
1172
  if (hasOtherAttachedSlotChildren && child instanceof TextSlotRenderable && this.getTextNodeForParent(parent) === child) {
1169
1173
  this.textNodesByParent.delete(parent);
1170
1174
  child.disposeWithoutSlotCascade();
@@ -1173,12 +1177,9 @@ class SlotRenderable extends SlotBaseRenderable {
1173
1177
  this.layoutNodesByParent.delete(parent);
1174
1178
  child.disposeWithoutSlotCascade();
1175
1179
  }
1176
- if (this.parent === parent) {
1177
- this.parent = this.getAttachedSlotParent(child);
1178
- }
1179
1180
  }
1180
1181
  didDestroySlotChild(child) {
1181
- const nodesByParent = child instanceof LayoutSlotRenderable ? this.layoutNodesByParent : this.textNodesByParent;
1182
+ const nodesByParent = child instanceof TextSlotRenderable ? this.textNodesByParent : this.layoutNodesByParent;
1182
1183
  for (const [parent, node] of nodesByParent) {
1183
1184
  if (node !== child)
1184
1185
  continue;
@@ -1193,22 +1194,24 @@ class SlotRenderable extends SlotBaseRenderable {
1193
1194
  }
1194
1195
  this.destroyed = true;
1195
1196
  this.parent = null;
1196
- const layoutNodes = new Set(this.layoutNodesByParent.values());
1197
+ const nodes = new Set([...this.layoutNodesByParent.values(), ...this.textNodesByParent.values()]);
1197
1198
  this.layoutNodesByParent.clear();
1198
- for (const layoutNode of layoutNodes) {
1199
- layoutNode.destroy();
1200
- }
1201
- const textNodes = new Set(this.textNodesByParent.values());
1202
1199
  this.textNodesByParent.clear();
1203
- for (const textNode of textNodes) {
1204
- textNode.destroy();
1200
+ let failure;
1201
+ for (const node of nodes) {
1202
+ try {
1203
+ node.destroy();
1204
+ } catch (error) {
1205
+ failure ??= { error };
1206
+ }
1205
1207
  }
1208
+ if (failure)
1209
+ throw failure.error;
1206
1210
  }
1207
1211
  }
1208
1212
  // src/scrollback.ts
1209
1213
  import {
1210
- BoxRenderable as BoxRenderable2,
1211
- RootRenderable
1214
+ BoxRenderable as BoxRenderable2
1212
1215
  } from "@opentui/core";
1213
1216
  import { createSignal as createSignal2 } from "solid-js";
1214
1217
  var solidScrollbackRootCounter = 0;
@@ -1222,17 +1225,12 @@ function normalizeSnapshotDimension(value, axis) {
1222
1225
  }
1223
1226
  return Math.max(1, Math.trunc(value));
1224
1227
  }
1225
- function createSnapshotRendererValue(renderContext, root, width, height, firstLineOffset) {
1228
+ function createSnapshotRendererValue(renderContext, width, height, firstLineOffset) {
1226
1229
  const [snapshotWidth] = createSignal2(width);
1227
1230
  const [snapshotHeight, setSnapshotHeight] = createSignal2(height);
1228
1231
  const renderer = Object.create(renderContext);
1229
1232
  let offset = firstLineOffset;
1230
1233
  Object.defineProperties(renderer, {
1231
- root: {
1232
- value: root,
1233
- enumerable: true,
1234
- configurable: true
1235
- },
1236
1234
  width: {
1237
1235
  get: snapshotWidth,
1238
1236
  enumerable: true,
@@ -1262,40 +1260,21 @@ function createSnapshotRendererValue(renderContext, root, width, height, firstLi
1262
1260
  }
1263
1261
  };
1264
1262
  }
1265
- function runLifecyclePasses(renderContext) {
1266
- for (const renderable of renderContext.getLifecyclePasses()) {
1267
- renderable.onLifecyclePass?.call(renderable);
1268
- }
1269
- }
1270
1263
  function clearLifecyclePasses(renderContext) {
1271
1264
  for (const renderable of [...renderContext.getLifecyclePasses()]) {
1272
1265
  renderContext.unregisterLifecyclePass(renderable);
1273
1266
  }
1274
1267
  }
1275
- function measureSnapshotHeight(renderContext, root) {
1276
- const measureRoot = new RootRenderable(renderContext);
1277
- try {
1278
- measureRoot.add(root);
1279
- runLifecyclePasses(renderContext);
1280
- measureRoot.calculateLayout();
1281
- return Math.max(1, Math.trunc(root.getLayoutNode().getComputedLayout().height));
1282
- } finally {
1283
- if (root.parent === measureRoot) {
1284
- measureRoot.remove(root);
1285
- }
1286
- measureRoot.destroyRecursively();
1287
- }
1288
- }
1289
1268
  function resolveSnapshotHeight(renderContext, root, snapshotRenderer) {
1290
1269
  for (let pass = 0;pass < MAX_AUTO_HEIGHT_PASSES; pass++) {
1291
- const measuredHeight = measureSnapshotHeight(renderContext, root);
1270
+ const measuredHeight = renderContext.nativeScene.measureSnapshot(root);
1292
1271
  if (measuredHeight === snapshotRenderer.getHeight()) {
1293
1272
  clearLifecyclePasses(renderContext);
1294
1273
  return measuredHeight;
1295
1274
  }
1296
1275
  snapshotRenderer.setHeight(measuredHeight);
1297
1276
  }
1298
- return measureSnapshotHeight(renderContext, root);
1277
+ return renderContext.nativeScene.measureSnapshot(root);
1299
1278
  }
1300
1279
  function createScrollbackWriter(node, options = {}) {
1301
1280
  return (ctx) => {
@@ -1304,7 +1283,8 @@ function createScrollbackWriter(node, options = {}) {
1304
1283
  const startOnNewLine = options.startOnNewLine ?? true;
1305
1284
  const firstLineWidth = !startOnNewLine && ctx.tailColumn > 0 && ctx.tailColumn < ctx.width ? Math.min(width, ctx.width - ctx.tailColumn) : width;
1306
1285
  const firstLineOffset = width - firstLineWidth;
1307
- const root = new BoxRenderable2(ctx.renderContext, {
1286
+ const snapshotRenderer = createSnapshotRendererValue(ctx.renderContext, width, height ?? Math.max(1, ctx.renderContext.height), firstLineOffset);
1287
+ const root = new BoxRenderable2(snapshotRenderer.renderer, {
1308
1288
  id: `solid-scrollback-root-${solidScrollbackRootCounter++}`,
1309
1289
  position: "absolute",
1310
1290
  left: 0,
@@ -1316,7 +1296,7 @@ function createScrollbackWriter(node, options = {}) {
1316
1296
  shouldFill: false,
1317
1297
  flexDirection: "column"
1318
1298
  });
1319
- const snapshotRenderer = createSnapshotRendererValue(ctx.renderContext, root, width, height ?? Math.max(1, ctx.renderContext.height), firstLineOffset);
1299
+ Object.defineProperty(snapshotRenderer.renderer, "root", { value: root, enumerable: true, configurable: true });
1320
1300
  let dispose;
1321
1301
  let disposed = false;
1322
1302
  const teardown = () => {
@@ -1538,6 +1518,9 @@ function Slot(props) {
1538
1518
 
1539
1519
  // index.ts
1540
1520
  var mountSolidRoot = (renderer, node) => {
1521
+ if (renderer.isDestroyed)
1522
+ return;
1523
+ engine.attach(renderer);
1541
1524
  let dispose;
1542
1525
  let disposeRequested = false;
1543
1526
  let disposed = false;
@@ -1590,7 +1573,6 @@ var render = async (node, rendererOrConfig = {}) => {
1590
1573
  rendererOrConfig.onDestroy?.();
1591
1574
  }
1592
1575
  });
1593
- engine2.attach(renderer);
1594
1576
  mountSolidRoot(renderer, node);
1595
1577
  };
1596
1578
  var testRender = async (node, renderConfig = {}) => {
@@ -1600,7 +1582,6 @@ var testRender = async (node, renderConfig = {}) => {
1600
1582
  renderConfig.onDestroy?.();
1601
1583
  }
1602
1584
  });
1603
- engine2.attach(testSetup.renderer);
1604
1585
  mountSolidRoot(testSetup.renderer, node);
1605
1586
  return testSetup;
1606
1587
  };
@@ -1612,6 +1593,7 @@ export {
1612
1593
  LineBreakRenderable,
1613
1594
  LinkRenderable,
1614
1595
  Portal,
1596
+ RenderableContext,
1615
1597
  RendererContext,
1616
1598
  Slot,
1617
1599
  SlotRenderable,
@@ -1639,6 +1621,7 @@ export {
1639
1621
  onBlur,
1640
1622
  onFocus,
1641
1623
  onResize,
1624
+ _removeNode as removeNode,
1642
1625
  render,
1643
1626
  setProp,
1644
1627
  spread,
@@ -1655,4 +1638,4 @@ export {
1655
1638
  writeSolidToScrollback
1656
1639
  };
1657
1640
 
1658
- //# debugId=F9161E10B307223364756E2164756E21
1641
+ //# debugId=37F996794E25432664756E2164756E21