@visulima/tui 0.0.1 → 1.0.0-alpha.2
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/CHANGELOG.md +200 -0
- package/LICENSE.md +303 -0
- package/README.md +173 -29
- package/dist/core/app.d.ts +50 -0
- package/dist/core/cell.d.ts +33 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.js +5 -0
- package/dist/core/inline.d.ts +22 -0
- package/dist/core/input.d.ts +18 -0
- package/dist/core/native-binding.d.ts +22 -0
- package/dist/ink/ansi-to-cell.d.ts +5 -0
- package/dist/ink/ansi-tokenizer.d.ts +38 -0
- package/dist/ink/clipboard.d.ts +29 -0
- package/dist/ink/color-matrix.d.ts +49 -0
- package/dist/ink/color-utils.d.ts +30 -0
- package/dist/ink/colorize.d.ts +4 -0
- package/dist/ink/components/AccessibilityContext.d.ts +4 -0
- package/dist/ink/components/Alert.d.ts +30 -0
- package/dist/ink/components/AnimationContext.d.ts +10 -0
- package/dist/ink/components/App.d.ts +19 -0
- package/dist/ink/components/AppContext.d.ts +38 -0
- package/dist/ink/components/BackgroundContext.d.ts +5 -0
- package/dist/ink/components/Badge.d.ts +27 -0
- package/dist/ink/components/BigText.d.ts +71 -0
- package/dist/ink/components/Box.d.ts +58 -0
- package/dist/ink/components/Code.d.ts +46 -0
- package/dist/ink/components/ConfirmInput.d.ts +40 -0
- package/dist/ink/components/ConsoleOverlay.d.ts +52 -0
- package/dist/ink/components/Cursor.d.ts +43 -0
- package/dist/ink/components/CursorContext.d.ts +12 -0
- package/dist/ink/components/Dialog.d.ts +93 -0
- package/dist/ink/components/DiffView.d.ts +71 -0
- package/dist/ink/components/ErrorBoundary.d.ts +17 -0
- package/dist/ink/components/ErrorOverview.d.ts +6 -0
- package/dist/ink/components/FocusContext.d.ts +17 -0
- package/dist/ink/components/Gradient.d.ts +38 -0
- package/dist/ink/components/Help.d.ts +49 -0
- package/dist/ink/components/Link.d.ts +34 -0
- package/dist/ink/components/Markdown.d.ts +34 -0
- package/dist/ink/components/MultiSelect.d.ts +63 -0
- package/dist/ink/components/Newline.d.ts +12 -0
- package/dist/ink/components/OrderedList.d.ts +30 -0
- package/dist/ink/components/Paginator.d.ts +75 -0
- package/dist/ink/components/ProgressBar.d.ts +51 -0
- package/dist/ink/components/SelectInput.d.ts +96 -0
- package/dist/ink/components/SelectInputIndicator.d.ts +36 -0
- package/dist/ink/components/SelectInputItem.d.ts +43 -0
- package/dist/ink/components/Slider.d.ts +92 -0
- package/dist/ink/components/Spacer.d.ts +7 -0
- package/dist/ink/components/Spinner.d.ts +42 -0
- package/dist/ink/components/Static.d.ts +24 -0
- package/dist/ink/components/StaticRender.d.ts +28 -0
- package/dist/ink/components/StatusMessage.d.ts +26 -0
- package/dist/ink/components/StderrContext.d.ts +16 -0
- package/dist/ink/components/StdinContext.d.ts +29 -0
- package/dist/ink/components/StdoutContext.d.ts +16 -0
- package/dist/ink/components/Stopwatch.d.ts +44 -0
- package/dist/ink/components/Tab.d.ts +25 -0
- package/dist/ink/components/Table.d.ts +80 -0
- package/dist/ink/components/Tabs.d.ts +104 -0
- package/dist/ink/components/Text.d.ts +63 -0
- package/dist/ink/components/TextInput.d.ts +48 -0
- package/dist/ink/components/Textarea.d.ts +62 -0
- package/dist/ink/components/Timer.d.ts +52 -0
- package/dist/ink/components/Transform.d.ts +16 -0
- package/dist/ink/components/UnorderedList.d.ts +35 -0
- package/dist/ink/components/file-picker/FilePicker.d.ts +75 -0
- package/dist/ink/components/file-picker/index.d.ts +3 -0
- package/dist/ink/components/file-picker/types.d.ts +38 -0
- package/dist/ink/components/file-picker/use-file-system.d.ts +16 -0
- package/dist/ink/components/scroll/ControlledScrollView.d.ts +43 -0
- package/dist/ink/components/scroll/ScrollBar.d.ts +20 -0
- package/dist/ink/components/scroll/ScrollBarBox.d.ts +15 -0
- package/dist/ink/components/scroll/ScrollList.d.ts +12 -0
- package/dist/ink/components/scroll/ScrollView.d.ts +98 -0
- package/dist/ink/components/scroll/index.d.ts +10 -0
- package/dist/ink/components/scroll/use-state-ref.d.ts +8 -0
- package/dist/ink/components/tree-view/TreeView.d.ts +89 -0
- package/dist/ink/components/tree-view/TreeViewNode.d.ts +29 -0
- package/dist/ink/components/tree-view/index.d.ts +11 -0
- package/dist/ink/components/tree-view/theme.d.ts +24 -0
- package/dist/ink/components/tree-view/tree-node-map.d.ts +72 -0
- package/dist/ink/components/tree-view/types.d.ts +55 -0
- package/dist/ink/components/tree-view/use-tree-view-state.d.ts +135 -0
- package/dist/ink/components/tree-view/use-tree-view.d.ts +26 -0
- package/dist/ink/components/variant-config.d.ts +10 -0
- package/dist/ink/cursor-helpers.d.ts +38 -0
- package/dist/ink/data-limited-lru-map.d.ts +21 -0
- package/dist/ink/devtools-window-polyfill.d.ts +1 -0
- package/dist/ink/devtools.d.ts +1 -0
- package/dist/ink/dom.d.ts +213 -0
- package/dist/ink/get-max-width.d.ts +3 -0
- package/dist/ink/highlighter.d.ts +28 -0
- package/dist/ink/hooks/use-animation.d.ts +43 -0
- package/dist/ink/hooks/use-app.d.ts +6 -0
- package/dist/ink/hooks/use-box-metrics.d.ts +58 -0
- package/dist/ink/hooks/use-clipboard.d.ts +29 -0
- package/dist/ink/hooks/use-color-blindness.d.ts +33 -0
- package/dist/ink/hooks/use-console-capture.d.ts +43 -0
- package/dist/ink/hooks/use-cursor.d.ts +12 -0
- package/dist/ink/hooks/use-focus-manager.d.ts +42 -0
- package/dist/ink/hooks/use-focus.d.ts +30 -0
- package/dist/ink/hooks/use-input.d.ts +149 -0
- package/dist/ink/hooks/use-is-screen-reader-enabled.d.ts +6 -0
- package/dist/ink/hooks/use-key-bindings.d.ts +61 -0
- package/dist/ink/hooks/use-linked-scroll.d.ts +41 -0
- package/dist/ink/hooks/use-paste.d.ts +44 -0
- package/dist/ink/hooks/use-scroll-acceleration.d.ts +47 -0
- package/dist/ink/hooks/use-scroll-input.d.ts +34 -0
- package/dist/ink/hooks/use-stderr.d.ts +6 -0
- package/dist/ink/hooks/use-stdin.d.ts +7 -0
- package/dist/ink/hooks/use-stdout.d.ts +6 -0
- package/dist/ink/hooks/use-stopwatch.d.ts +40 -0
- package/dist/ink/hooks/use-terminal-palette.d.ts +19 -0
- package/dist/ink/hooks/use-text-buffer.d.ts +42 -0
- package/dist/ink/hooks/use-text-selection.d.ts +45 -0
- package/dist/ink/hooks/use-timer.d.ts +49 -0
- package/dist/ink/hooks/use-window-size.d.ts +18 -0
- package/dist/ink/ime-utils.d.ts +25 -0
- package/dist/ink/index.d.ts +159 -0
- package/dist/ink/index.js +100 -0
- package/dist/ink/ink.d.ts +189 -0
- package/dist/ink/input-parser.d.ts +10 -0
- package/dist/ink/input-utils.d.ts +16 -0
- package/dist/ink/instances.d.ts +3 -0
- package/dist/ink/kitty-keyboard.d.ts +23 -0
- package/dist/ink/layout.d.ts +26 -0
- package/dist/ink/log-update-native.d.ts +14 -0
- package/dist/ink/log-update.d.ts +21 -0
- package/dist/ink/measure-element.d.ts +147 -0
- package/dist/ink/measure-text.d.ts +56 -0
- package/dist/ink/mouse/Fullscreen.d.ts +8 -0
- package/dist/ink/mouse/MouseProvider.d.ts +11 -0
- package/dist/ink/mouse/ansi-parser.d.ts +37 -0
- package/dist/ink/mouse/constants.d.ts +59 -0
- package/dist/ink/mouse/index.d.ts +20 -0
- package/dist/ink/mouse/is-intersecting.d.ts +18 -0
- package/dist/ink/mouse/mouse-context.d.ts +36 -0
- package/dist/ink/mouse/use-element-position.d.ts +29 -0
- package/dist/ink/mouse/use-mouse-action.d.ts +7 -0
- package/dist/ink/mouse/use-mouse-position.d.ts +7 -0
- package/dist/ink/mouse/use-mouse.d.ts +7 -0
- package/dist/ink/mouse/use-on-mouse-click.d.ts +14 -0
- package/dist/ink/mouse/use-on-mouse-hover.d.ts +8 -0
- package/dist/ink/mouse/use-on-mouse-state.d.ts +11 -0
- package/dist/ink/output.d.ts +74 -0
- package/dist/ink/parse-keypress.d.ts +22 -0
- package/dist/ink/reconciler.d.ts +3 -0
- package/dist/ink/region.d.ts +99 -0
- package/dist/ink/render-background.d.ts +4 -0
- package/dist/ink/render-border.d.ts +4 -0
- package/dist/ink/render-node-to-output.d.ts +38 -0
- package/dist/ink/render-scrollbar.d.ts +9 -0
- package/dist/ink/render-sticky.d.ts +44 -0
- package/dist/ink/render-to-string.d.ts +37 -0
- package/dist/ink/render.d.ts +191 -0
- package/dist/ink/renderer.d.ts +17 -0
- package/dist/ink/resize-observer.d.ts +44 -0
- package/dist/ink/sanitize-ansi.d.ts +2 -0
- package/dist/ink/scroll.d.ts +23 -0
- package/dist/ink/selection.d.ts +70 -0
- package/dist/ink/squash-text-nodes.d.ts +18 -0
- package/dist/ink/style-flags.d.ts +17 -0
- package/dist/ink/styled-line-factory.d.ts +25 -0
- package/dist/ink/styled-line-serializer.d.ts +18 -0
- package/dist/ink/styled-line.d.ts +109 -0
- package/dist/ink/styles.d.ts +369 -0
- package/dist/ink/terminal-palette.d.ts +25 -0
- package/dist/ink/text-wrap.d.ts +10 -0
- package/dist/ink/token-to-elements.d.ts +22 -0
- package/dist/ink/utils/format-time.d.ts +4 -0
- package/dist/ink/utils.d.ts +9 -0
- package/dist/ink/wrap-text.d.ts +3 -0
- package/dist/ink/write-synchronized.d.ts +4 -0
- package/dist/packem_chunks/devtools.js +27 -0
- package/dist/packem_shared/AccessibilityContext-BLelHhNU.js +7 -0
- package/dist/packem_shared/Alert-Dr3s_LD9.js +17 -0
- package/dist/packem_shared/AnimationContext-BcJg8Jr6.js +15 -0
- package/dist/packem_shared/AppContext-CP0U6H7O.js +11 -0
- package/dist/packem_shared/BackgroundContext-BAUaxfOb.js +5 -0
- package/dist/packem_shared/Badge-Dk7EGGM6.js +13 -0
- package/dist/packem_shared/BigText-CjMdY63X.js +24 -0
- package/dist/packem_shared/Box-D_pSJ9Jp.js +73 -0
- package/dist/packem_shared/COLOR_BLINDNESS_SIMULATION-BsMy5Ewl.js +81 -0
- package/dist/packem_shared/Cell-DCg1kJY-.js +48 -0
- package/dist/packem_shared/Code-DjQvPBD9.js +53 -0
- package/dist/packem_shared/ConfirmInput-85Y4kRQW.js +44 -0
- package/dist/packem_shared/ConsoleOverlay-DBNa4vtj.js +57 -0
- package/dist/packem_shared/ControlledScrollView-BlOaxcsN.js +286 -0
- package/dist/packem_shared/ControlledScrollView-DfAhcufF.js +5 -0
- package/dist/packem_shared/Cursor-DiW7YoSK.js +18 -0
- package/dist/packem_shared/CursorContext-JxRzlqAx.js +9 -0
- package/dist/packem_shared/DevTools-aMPIsaHx.js +61 -0
- package/dist/packem_shared/Dialog-DsSNAVgC.js +71 -0
- package/dist/packem_shared/DiffView-hqaw-2S6.js +329 -0
- package/dist/packem_shared/FilePicker-DNwFxRhq.js +254 -0
- package/dist/packem_shared/FocusContext-CWkYtgcm.js +26 -0
- package/dist/packem_shared/FocusContext-D5wFxSRz.js +153 -0
- package/dist/packem_shared/Fullscreen-DrElAE1o.js +11 -0
- package/dist/packem_shared/Gradient-Ql5P0GUd.js +136 -0
- package/dist/packem_shared/Help-6wanGG38.js +112 -0
- package/dist/packem_shared/IMECompositionBuffer-Dl3S0KnF.js +55 -0
- package/dist/packem_shared/InputParser-BKHpWfvN.js +156 -0
- package/dist/packem_shared/LayoutNode-Cjnsodiy.js +131 -0
- package/dist/packem_shared/Link-COcKYfGT.js +66 -0
- package/dist/packem_shared/Markdown-y1ISztof.js +212 -0
- package/dist/packem_shared/MouseProvider-Y9TSSEGl.js +136 -0
- package/dist/packem_shared/MultiSelect-ChoLUcDI.js +129 -0
- package/dist/packem_shared/NAMED_COLORS-a4QBvb5r.js +262 -0
- package/dist/packem_shared/Newline-DBtYEg8x.js +7 -0
- package/dist/packem_shared/OrderedList-Cp7pXr6m.js +26 -0
- package/dist/packem_shared/Paginator-D1AuD-kj.js +104 -0
- package/dist/packem_shared/ProgressBar-DOfpVagn.js +22 -0
- package/dist/packem_shared/Renderer-zZ5O3vxc.js +31 -0
- package/dist/packem_shared/ResizeObserverEntry-Br4seLeQ.js +102 -0
- package/dist/packem_shared/ScrollBar-EWAs2Uc7.js +106 -0
- package/dist/packem_shared/ScrollBarBox-DTNNlh7R.js +72 -0
- package/dist/packem_shared/ScrollList-DCeIFL8M.js +227 -0
- package/dist/packem_shared/ScrollView-v3MCNIyX.js +196 -0
- package/dist/packem_shared/SelectInput-BN2TMyxp.js +260 -0
- package/dist/packem_shared/SelectInputIndicator-DkRMoH_b.js +9 -0
- package/dist/packem_shared/SelectInputItem-BF9LQgKu.js +8 -0
- package/dist/packem_shared/Slider-BWD7xZX6.js +116 -0
- package/dist/packem_shared/Spacer-Bs4ER-HK.js +8 -0
- package/dist/packem_shared/Spinner-BuI-kN4p.js +1799 -0
- package/dist/packem_shared/Static-DpTd6Eed.js +22 -0
- package/dist/packem_shared/Static-xmD9giJj.js +18 -0
- package/dist/packem_shared/StaticRender-tYwH6QXl.js +33 -0
- package/dist/packem_shared/StatusMessage-BtSYxzwb.js +14 -0
- package/dist/packem_shared/StderrContext-Bj4Mf7v7.js +17 -0
- package/dist/packem_shared/StdinContext-Bq_GNJ3z.js +38 -0
- package/dist/packem_shared/StdoutContext-CgjWeCdO.js +17 -0
- package/dist/packem_shared/Stopwatch-DjtTCyHn.js +23 -0
- package/dist/packem_shared/Tab-C6r5q4hR.js +7 -0
- package/dist/packem_shared/Table-D-rSVlzb.js +82 -0
- package/dist/packem_shared/Tabs-hki-KRnx.js +153 -0
- package/dist/packem_shared/Text-DvAUdZcK.js +65 -0
- package/dist/packem_shared/TextInput-C79WEQ5U.js +137 -0
- package/dist/packem_shared/Textarea-Dj06R6Zd.js +272 -0
- package/dist/packem_shared/Timer-wi9zuh4n.js +22 -0
- package/dist/packem_shared/Transform-BHxY_dAM.js +14 -0
- package/dist/packem_shared/TreeNodeMap-CtJUvBnd.js +155 -0
- package/dist/packem_shared/TreeView-C2062dtj.js +148 -0
- package/dist/packem_shared/TuiApp-DfxOnXqi.js +120 -0
- package/dist/packem_shared/TuiContext-CqEjMyXd.js +415 -0
- package/dist/packem_shared/UnorderedList-DhnadWjX.js +33 -0
- package/dist/packem_shared/ansi-parser-0BdVTKho.js +41 -0
- package/dist/packem_shared/ansi-tokenizer-LHq2LUWA.js +307 -0
- package/dist/packem_shared/boxes-oi3WUbyR.js +92 -0
- package/dist/packem_shared/colorize-88_Vk8cn.js +48 -0
- package/dist/packem_shared/comparePoints-CGMDnd3_.js +287 -0
- package/dist/packem_shared/createInlineLoop-BxMmcq9D.js +93 -0
- package/dist/packem_shared/createLinkedScrollGroup-Djw4Ceo0.js +44 -0
- package/dist/packem_shared/dom-DvzhsAez.js +225 -0
- package/dist/packem_shared/format-time-BGmnDukX.js +12 -0
- package/dist/packem_shared/getPathToRoot-a1wbwxfL.js +4 -0
- package/dist/packem_shared/getScrollHeight-BubfU_df.js +63 -0
- package/dist/packem_shared/input-utils-ViAEXa0Z.js +19 -0
- package/dist/packem_shared/isIntersecting-fEXHJN5R.js +10 -0
- package/dist/packem_shared/isOsc52Supported-G0k4sXJx.js +36 -0
- package/dist/packem_shared/isTerminalPaletteQuerySupported-EeiwMKbr.js +93 -0
- package/dist/packem_shared/kittyFlags-bNNf_9kX.js +26 -0
- package/dist/packem_shared/measure-element-Reza_yfC.js +396 -0
- package/dist/packem_shared/measure-text-DItZYotK.js +1189 -0
- package/dist/packem_shared/measureElement-CTgFCmKd.js +4 -0
- package/dist/packem_shared/mouse-context-BUHWKEIe.js +6 -0
- package/dist/packem_shared/parseSgrMouse-BHVBPP9G.js +1 -0
- package/dist/packem_shared/processLayout-BQ9kXfd3.js +2 -0
- package/dist/packem_shared/reconciler-BXf6miSS.js +211 -0
- package/dist/packem_shared/reconciler-gfmqURLy.js +680 -0
- package/dist/packem_shared/render-BAwdjfki.js +2806 -0
- package/dist/packem_shared/render-Bpjhf0lD.js +195 -0
- package/dist/packem_shared/renderToString-Cfg55DRD.js +62 -0
- package/dist/packem_shared/renderToString-ClIaXgrC.js +86 -0
- package/dist/packem_shared/renderTreeToBuffer-D3mo7M7m.js +308 -0
- package/dist/packem_shared/renderer-B3wROkeg.js +1431 -0
- package/dist/packem_shared/setEnableStyledLineCache-BpskngSJ.js +2 -0
- package/dist/packem_shared/squashTextNodesWithMap-iqm6OMMT.js +100 -0
- package/dist/packem_shared/text-width-DhuarWcB.js +42 -0
- package/dist/packem_shared/token-to-elements-BRFl_rzw.js +249 -0
- package/dist/packem_shared/treeViewTheme-BpSw9TMf.js +52 -0
- package/dist/packem_shared/useAnimation-kj31sA-T.js +62 -0
- package/dist/packem_shared/useApp-DPQlRzi5.js +6 -0
- package/dist/packem_shared/useBoxMetrics-rBjKc-g4.js +54 -0
- package/dist/packem_shared/useClipboard-B_9-adw1.js +23 -0
- package/dist/packem_shared/useColorBlindness-D_sTIhcb.js +30 -0
- package/dist/packem_shared/useConsoleCapture-Dvt7G1W1.js +61 -0
- package/dist/packem_shared/useCursor-BIJzc8k9.js +19 -0
- package/dist/packem_shared/useElementDimensions-CAoKitVD.js +67 -0
- package/dist/packem_shared/useFocus-CNl5QHHf.js +37 -0
- package/dist/packem_shared/useFocusManager-BPYaUuKQ.js +16 -0
- package/dist/packem_shared/useInput-Cfp5zB2s.js +594 -0
- package/dist/packem_shared/useIsScreenReaderEnabled-CnGKCe0f.js +9 -0
- package/dist/packem_shared/useKeyBindings-B78l1E1n.js +66 -0
- package/dist/packem_shared/useMouseAction-C5gZ2nj7.js +29 -0
- package/dist/packem_shared/useMouseContext-D-rFy60Q.js +12 -0
- package/dist/packem_shared/useMousePosition-BHBJ-kBk.js +25 -0
- package/dist/packem_shared/useOnMouseClick--ZIyBOBO.js +35 -0
- package/dist/packem_shared/useOnMouseHover-26diuXUC.js +32 -0
- package/dist/packem_shared/useOnMouseState-NO_Kda_C.js +13 -0
- package/dist/packem_shared/usePaste-Ct8J4AGR.js +35 -0
- package/dist/packem_shared/useScrollAcceleration-R9LfrPVG.js +73 -0
- package/dist/packem_shared/useScrollInput-D3CpBq_a.js +72 -0
- package/dist/packem_shared/useStderr-CAOVUh4E.js +6 -0
- package/dist/packem_shared/useStdin-X-O0kd-n.js +7 -0
- package/dist/packem_shared/useStdout-DyF6DSH0.js +6 -0
- package/dist/packem_shared/useStopwatch-qC4Beai4.js +33 -0
- package/dist/packem_shared/useTerminalPalette-BaWO2c4Q.js +38 -0
- package/dist/packem_shared/useTextBuffer-C8fEe9Ly.js +398 -0
- package/dist/packem_shared/useTextSelection-mXtxgsPK.js +50 -0
- package/dist/packem_shared/useTimer-CPQ7j827.js +46 -0
- package/dist/packem_shared/useTreeView-BT57P3Kx.js +101 -0
- package/dist/packem_shared/useTreeViewState-BpS_KZ-K.js +502 -0
- package/dist/packem_shared/useWindowSize-ugEmGZJm.js +20 -0
- package/dist/packem_shared/utils-BgdlrbOH.js +140 -0
- package/dist/packem_shared/variant-config-DSZoX5TM.js +8 -0
- package/dist/packem_shared/wrapOrTruncateStyledLine-DN3Nogoc.js +147 -0
- package/dist/react/devtools.d.ts +27 -0
- package/dist/react/focus.d.ts +39 -0
- package/dist/react/hooks.d.ts +238 -0
- package/dist/react/index.d.ts +8 -0
- package/dist/react/index.js +9 -0
- package/dist/react/layout.d.ts +35 -0
- package/dist/react/react.d.ts +57 -0
- package/dist/react/reconciler.d.ts +4 -0
- package/dist/react/render-to-string.d.ts +21 -0
- package/dist/react/renderer.d.ts +2 -0
- package/dist/react/scene.d.ts +3 -0
- package/dist/react/static.d.ts +39 -0
- package/dist/react/styles.d.ts +83 -0
- package/dist/react/text-width.d.ts +20 -0
- package/dist/testing/index.d.ts +144 -0
- package/dist/testing/index.js +260 -0
- package/dist/testing/keys.d.ts +89 -0
- package/dist/testing/screen.d.ts +35 -0
- package/dist/testing/wait-for.d.ts +21 -0
- package/index.js +585 -0
- package/package.json +117 -7
|
@@ -0,0 +1,2806 @@
|
|
|
1
|
+
import { createRequire as __cjs_createRequire } from "node:module";
|
|
2
|
+
|
|
3
|
+
const __cjs_require = __cjs_createRequire(import.meta.url);
|
|
4
|
+
|
|
5
|
+
const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
|
|
6
|
+
|
|
7
|
+
const __cjs_getBuiltinModule = (module) => {
|
|
8
|
+
// Check if we're in Node.js and version supports getBuiltinModule
|
|
9
|
+
if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
|
|
10
|
+
const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
|
|
11
|
+
// Node.js 20.16.0+ and 22.3.0+
|
|
12
|
+
if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
|
|
13
|
+
return __cjs_getProcess.getBuiltinModule(module);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
// Fallback to createRequire
|
|
17
|
+
return __cjs_require(module);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const process$2 = __cjs_getProcess;
|
|
21
|
+
const {
|
|
22
|
+
env,
|
|
23
|
+
cwd
|
|
24
|
+
} = process$2;
|
|
25
|
+
const {
|
|
26
|
+
Stream
|
|
27
|
+
} = __cjs_getBuiltinModule("node:stream");
|
|
28
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
29
|
+
const {
|
|
30
|
+
Buffer
|
|
31
|
+
} = __cjs_getBuiltinModule("node:buffer");
|
|
32
|
+
const {
|
|
33
|
+
Console
|
|
34
|
+
} = __cjs_getBuiltinModule("node:console");
|
|
35
|
+
import { cursorShow, cursorUp, cursorTo, cursorDown, eraseLines, cursorHide, cursorNextLine, eraseLineEnd, ALT_SCREEN_ON, resetTerminal, ALT_SCREEN_OFF } from '@visulima/ansi';
|
|
36
|
+
import { wordWrap } from '@visulima/string';
|
|
37
|
+
import patchConsole from 'patch-console';
|
|
38
|
+
import { ConcurrentRoot, LegacyRoot } from 'react-reconciler/constants.js';
|
|
39
|
+
import Yoga from 'yoga-layout';
|
|
40
|
+
import { a as accessibilityContext } from './AccessibilityContext-BLelHhNU.js';
|
|
41
|
+
const {
|
|
42
|
+
EventEmitter
|
|
43
|
+
} = __cjs_getBuiltinModule("node:events");
|
|
44
|
+
import { PureComponent, useState, useRef, useCallback, useEffect, useMemo } from 'react';
|
|
45
|
+
import { a as animationContext } from './AnimationContext-BcJg8Jr6.js';
|
|
46
|
+
import { A as AppContext } from './AppContext-CP0U6H7O.js';
|
|
47
|
+
import { C as CursorContext } from './CursorContext-JxRzlqAx.js';
|
|
48
|
+
const {
|
|
49
|
+
existsSync,
|
|
50
|
+
readFileSync
|
|
51
|
+
} = __cjs_getBuiltinModule("node:fs");
|
|
52
|
+
const require$$1 = __cjs_getBuiltinModule("module");
|
|
53
|
+
import Box from './Box-D_pSJ9Jp.js';
|
|
54
|
+
import Text from './Text-DvAUdZcK.js';
|
|
55
|
+
import { F as FocusContext } from './FocusContext-CWkYtgcm.js';
|
|
56
|
+
import { S as StderrContext } from './StderrContext-Bj4Mf7v7.js';
|
|
57
|
+
import { S as StdinContext } from './StdinContext-Bq_GNJ3z.js';
|
|
58
|
+
import { S as StdoutContext } from './StdoutContext-CgjWeCdO.js';
|
|
59
|
+
import { c as createNode } from './dom-DvzhsAez.js';
|
|
60
|
+
import { resolveFlags } from './kittyFlags-bNNf_9kX.js';
|
|
61
|
+
import { a as clearStyledLineCache } from './measure-text-DItZYotK.js';
|
|
62
|
+
import { r as reconcilerInstance, s as styles } from './reconciler-gfmqURLy.js';
|
|
63
|
+
import { a as renderToStatic, r as renderer } from './renderer-B3wROkeg.js';
|
|
64
|
+
import { measureAndExtractObservers } from './ResizeObserverEntry-Br4seLeQ.js';
|
|
65
|
+
import { calculateScroll } from './getScrollHeight-BubfU_df.js';
|
|
66
|
+
import { g as getWindowSize } from './utils-BgdlrbOH.js';
|
|
67
|
+
|
|
68
|
+
import __cjs_mod__ from "node:module"; // -- packem CommonJS require shim --
|
|
69
|
+
const require = __cjs_mod__.createRequire(import.meta.url);
|
|
70
|
+
function debounce$1(func, debounceMs, { signal, edges } = {}) {
|
|
71
|
+
let pendingThis = void 0;
|
|
72
|
+
let pendingArgs = null;
|
|
73
|
+
const leading = edges != null && edges.includes("leading");
|
|
74
|
+
const trailing = edges == null || edges.includes("trailing");
|
|
75
|
+
const invoke = () => {
|
|
76
|
+
if (pendingArgs !== null) {
|
|
77
|
+
func.apply(pendingThis, pendingArgs);
|
|
78
|
+
pendingThis = void 0;
|
|
79
|
+
pendingArgs = null;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const onTimerEnd = () => {
|
|
83
|
+
if (trailing) {
|
|
84
|
+
invoke();
|
|
85
|
+
}
|
|
86
|
+
cancel();
|
|
87
|
+
};
|
|
88
|
+
let timeoutId = null;
|
|
89
|
+
const schedule = () => {
|
|
90
|
+
if (timeoutId != null) {
|
|
91
|
+
clearTimeout(timeoutId);
|
|
92
|
+
}
|
|
93
|
+
timeoutId = setTimeout(() => {
|
|
94
|
+
timeoutId = null;
|
|
95
|
+
onTimerEnd();
|
|
96
|
+
}, debounceMs);
|
|
97
|
+
};
|
|
98
|
+
const cancelTimer = () => {
|
|
99
|
+
if (timeoutId !== null) {
|
|
100
|
+
clearTimeout(timeoutId);
|
|
101
|
+
timeoutId = null;
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const cancel = () => {
|
|
105
|
+
cancelTimer();
|
|
106
|
+
pendingThis = void 0;
|
|
107
|
+
pendingArgs = null;
|
|
108
|
+
};
|
|
109
|
+
const flush = () => {
|
|
110
|
+
invoke();
|
|
111
|
+
};
|
|
112
|
+
const debounced = function(...args) {
|
|
113
|
+
if (signal?.aborted) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
pendingThis = this;
|
|
117
|
+
pendingArgs = args;
|
|
118
|
+
const isFirstCall = timeoutId == null;
|
|
119
|
+
schedule();
|
|
120
|
+
if (leading && isFirstCall) {
|
|
121
|
+
invoke();
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
debounced.schedule = schedule;
|
|
125
|
+
debounced.cancel = cancel;
|
|
126
|
+
debounced.flush = flush;
|
|
127
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
128
|
+
return debounced;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function debounce(func, debounceMs = 0, options = {}) {
|
|
132
|
+
if (typeof options !== "object") {
|
|
133
|
+
options = {};
|
|
134
|
+
}
|
|
135
|
+
const { leading = false, trailing = true, maxWait } = options;
|
|
136
|
+
const edges = Array(2);
|
|
137
|
+
if (leading) {
|
|
138
|
+
edges[0] = "leading";
|
|
139
|
+
}
|
|
140
|
+
if (trailing) {
|
|
141
|
+
edges[1] = "trailing";
|
|
142
|
+
}
|
|
143
|
+
let result = void 0;
|
|
144
|
+
let pendingAt = null;
|
|
145
|
+
const _debounced = debounce$1(function(...args) {
|
|
146
|
+
result = func.apply(this, args);
|
|
147
|
+
pendingAt = null;
|
|
148
|
+
}, debounceMs, { edges });
|
|
149
|
+
const debounced = function(...args) {
|
|
150
|
+
if (maxWait != null) {
|
|
151
|
+
if (pendingAt === null) {
|
|
152
|
+
pendingAt = Date.now();
|
|
153
|
+
}
|
|
154
|
+
if (Date.now() - pendingAt >= maxWait) {
|
|
155
|
+
result = func.apply(this, args);
|
|
156
|
+
pendingAt = Date.now();
|
|
157
|
+
_debounced.cancel();
|
|
158
|
+
_debounced.schedule();
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
_debounced.apply(this, args);
|
|
163
|
+
return result;
|
|
164
|
+
};
|
|
165
|
+
const flush = () => {
|
|
166
|
+
_debounced.flush();
|
|
167
|
+
return result;
|
|
168
|
+
};
|
|
169
|
+
debounced.cancel = _debounced.cancel;
|
|
170
|
+
debounced.flush = flush;
|
|
171
|
+
return debounced;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function throttle(func, throttleMs = 0, options = {}) {
|
|
175
|
+
const { leading = true, trailing = true } = options;
|
|
176
|
+
return debounce(func, throttleMs, {
|
|
177
|
+
leading,
|
|
178
|
+
maxWait: throttleMs,
|
|
179
|
+
trailing
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const check = (key) => key in env && env[key] !== "0" && env[key] !== "false";
|
|
184
|
+
const isInCi = check("CI") || check("CONTINUOUS_INTEGRATION");
|
|
185
|
+
|
|
186
|
+
const signals = [];
|
|
187
|
+
signals.push("SIGHUP", "SIGINT", "SIGTERM");
|
|
188
|
+
if (process.platform !== "win32") {
|
|
189
|
+
signals.push(
|
|
190
|
+
"SIGALRM",
|
|
191
|
+
"SIGABRT",
|
|
192
|
+
"SIGVTALRM",
|
|
193
|
+
"SIGXCPU",
|
|
194
|
+
"SIGXFSZ",
|
|
195
|
+
"SIGUSR2",
|
|
196
|
+
"SIGTRAP",
|
|
197
|
+
"SIGSYS",
|
|
198
|
+
"SIGQUIT",
|
|
199
|
+
"SIGIOT"
|
|
200
|
+
// should detect profiler and enable/disable accordingly.
|
|
201
|
+
// see #21
|
|
202
|
+
// 'SIGPROF'
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
if (process.platform === "linux") {
|
|
206
|
+
signals.push("SIGIO", "SIGPOLL", "SIGPWR", "SIGSTKFLT");
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const processOk = (process2) => !!process2 && true && typeof process2.removeListener === "function" && typeof process2.emit === "function" && typeof process2.reallyExit === "function" && typeof process2.listeners === "function" && typeof process2.kill === "function" && typeof process2.pid === "number" && typeof process2.on === "function";
|
|
210
|
+
const kExitEmitter = /* @__PURE__ */ Symbol.for("signal-exit emitter");
|
|
211
|
+
const global = globalThis;
|
|
212
|
+
const ObjectDefineProperty = Object.defineProperty.bind(Object);
|
|
213
|
+
class Emitter {
|
|
214
|
+
emitted = {
|
|
215
|
+
afterExit: false,
|
|
216
|
+
exit: false
|
|
217
|
+
};
|
|
218
|
+
listeners = {
|
|
219
|
+
afterExit: [],
|
|
220
|
+
exit: []
|
|
221
|
+
};
|
|
222
|
+
count = 0;
|
|
223
|
+
id = Math.random();
|
|
224
|
+
constructor() {
|
|
225
|
+
if (global[kExitEmitter]) {
|
|
226
|
+
return global[kExitEmitter];
|
|
227
|
+
}
|
|
228
|
+
ObjectDefineProperty(global, kExitEmitter, {
|
|
229
|
+
value: this,
|
|
230
|
+
writable: false,
|
|
231
|
+
enumerable: false,
|
|
232
|
+
configurable: false
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
on(ev, fn) {
|
|
236
|
+
this.listeners[ev].push(fn);
|
|
237
|
+
}
|
|
238
|
+
removeListener(ev, fn) {
|
|
239
|
+
const list = this.listeners[ev];
|
|
240
|
+
const i = list.indexOf(fn);
|
|
241
|
+
if (i === -1) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
if (i === 0 && list.length === 1) {
|
|
245
|
+
list.length = 0;
|
|
246
|
+
} else {
|
|
247
|
+
list.splice(i, 1);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
emit(ev, code, signal) {
|
|
251
|
+
if (this.emitted[ev]) {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
this.emitted[ev] = true;
|
|
255
|
+
let ret = false;
|
|
256
|
+
for (const fn of this.listeners[ev]) {
|
|
257
|
+
ret = fn(code, signal) === true || ret;
|
|
258
|
+
}
|
|
259
|
+
if (ev === "exit") {
|
|
260
|
+
ret = this.emit("afterExit", code, signal) || ret;
|
|
261
|
+
}
|
|
262
|
+
return ret;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
class SignalExitBase {
|
|
266
|
+
}
|
|
267
|
+
const signalExitWrap = (handler) => {
|
|
268
|
+
return {
|
|
269
|
+
onExit(cb, opts) {
|
|
270
|
+
return handler.onExit(cb, opts);
|
|
271
|
+
},
|
|
272
|
+
load() {
|
|
273
|
+
return handler.load();
|
|
274
|
+
},
|
|
275
|
+
unload() {
|
|
276
|
+
return handler.unload();
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
};
|
|
280
|
+
class SignalExitFallback extends SignalExitBase {
|
|
281
|
+
onExit() {
|
|
282
|
+
return () => {
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
load() {
|
|
286
|
+
}
|
|
287
|
+
unload() {
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
class SignalExit extends SignalExitBase {
|
|
291
|
+
// "SIGHUP" throws an `ENOSYS` error on Windows,
|
|
292
|
+
// so use a supported signal instead
|
|
293
|
+
/* c8 ignore start */
|
|
294
|
+
#hupSig = process$1.platform === "win32" ? "SIGINT" : "SIGHUP";
|
|
295
|
+
/* c8 ignore stop */
|
|
296
|
+
#emitter = new Emitter();
|
|
297
|
+
#process;
|
|
298
|
+
#originalProcessEmit;
|
|
299
|
+
#originalProcessReallyExit;
|
|
300
|
+
#sigListeners = {};
|
|
301
|
+
#loaded = false;
|
|
302
|
+
constructor(process2) {
|
|
303
|
+
super();
|
|
304
|
+
this.#process = process2;
|
|
305
|
+
this.#sigListeners = {};
|
|
306
|
+
for (const sig of signals) {
|
|
307
|
+
this.#sigListeners[sig] = () => {
|
|
308
|
+
const listeners = this.#process.listeners(sig);
|
|
309
|
+
let { count } = this.#emitter;
|
|
310
|
+
const p = process2;
|
|
311
|
+
if (typeof p.__signal_exit_emitter__ === "object" && typeof p.__signal_exit_emitter__.count === "number") {
|
|
312
|
+
count += p.__signal_exit_emitter__.count;
|
|
313
|
+
}
|
|
314
|
+
if (listeners.length === count) {
|
|
315
|
+
this.unload();
|
|
316
|
+
const ret = this.#emitter.emit("exit", null, sig);
|
|
317
|
+
const s = sig === "SIGHUP" ? this.#hupSig : sig;
|
|
318
|
+
if (!ret)
|
|
319
|
+
process2.kill(process2.pid, s);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
this.#originalProcessReallyExit = process2.reallyExit;
|
|
324
|
+
this.#originalProcessEmit = process2.emit;
|
|
325
|
+
}
|
|
326
|
+
onExit(cb, opts) {
|
|
327
|
+
if (!processOk(this.#process)) {
|
|
328
|
+
return () => {
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
if (this.#loaded === false) {
|
|
332
|
+
this.load();
|
|
333
|
+
}
|
|
334
|
+
const ev = opts?.alwaysLast ? "afterExit" : "exit";
|
|
335
|
+
this.#emitter.on(ev, cb);
|
|
336
|
+
return () => {
|
|
337
|
+
this.#emitter.removeListener(ev, cb);
|
|
338
|
+
if (this.#emitter.listeners["exit"].length === 0 && this.#emitter.listeners["afterExit"].length === 0) {
|
|
339
|
+
this.unload();
|
|
340
|
+
}
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
load() {
|
|
344
|
+
if (this.#loaded) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
this.#loaded = true;
|
|
348
|
+
this.#emitter.count += 1;
|
|
349
|
+
for (const sig of signals) {
|
|
350
|
+
try {
|
|
351
|
+
const fn = this.#sigListeners[sig];
|
|
352
|
+
if (fn)
|
|
353
|
+
this.#process.on(sig, fn);
|
|
354
|
+
} catch (_) {
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
this.#process.emit = (ev, ...a) => {
|
|
358
|
+
return this.#processEmit(ev, ...a);
|
|
359
|
+
};
|
|
360
|
+
this.#process.reallyExit = (code) => {
|
|
361
|
+
return this.#processReallyExit(code);
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
unload() {
|
|
365
|
+
if (!this.#loaded) {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
this.#loaded = false;
|
|
369
|
+
signals.forEach((sig) => {
|
|
370
|
+
const listener = this.#sigListeners[sig];
|
|
371
|
+
if (!listener) {
|
|
372
|
+
throw new Error("Listener not defined for signal: " + sig);
|
|
373
|
+
}
|
|
374
|
+
try {
|
|
375
|
+
this.#process.removeListener(sig, listener);
|
|
376
|
+
} catch (_) {
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
this.#process.emit = this.#originalProcessEmit;
|
|
380
|
+
this.#process.reallyExit = this.#originalProcessReallyExit;
|
|
381
|
+
this.#emitter.count -= 1;
|
|
382
|
+
}
|
|
383
|
+
#processReallyExit(code) {
|
|
384
|
+
if (!processOk(this.#process)) {
|
|
385
|
+
return 0;
|
|
386
|
+
}
|
|
387
|
+
this.#process.exitCode = code || 0;
|
|
388
|
+
this.#emitter.emit("exit", this.#process.exitCode, null);
|
|
389
|
+
return this.#originalProcessReallyExit.call(this.#process, this.#process.exitCode);
|
|
390
|
+
}
|
|
391
|
+
#processEmit(ev, ...args) {
|
|
392
|
+
const og = this.#originalProcessEmit;
|
|
393
|
+
if (ev === "exit" && processOk(this.#process)) {
|
|
394
|
+
if (typeof args[0] === "number") {
|
|
395
|
+
this.#process.exitCode = args[0];
|
|
396
|
+
}
|
|
397
|
+
const ret = og.call(this.#process, ev, ...args);
|
|
398
|
+
this.#emitter.emit("exit", this.#process.exitCode, null);
|
|
399
|
+
return ret;
|
|
400
|
+
} else {
|
|
401
|
+
return og.call(this.#process, ev, ...args);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
const process$1 = globalThis.process;
|
|
406
|
+
const {
|
|
407
|
+
/**
|
|
408
|
+
* Called when the process is exiting, whether via signal, explicit
|
|
409
|
+
* exit, or running out of stuff to do.
|
|
410
|
+
*
|
|
411
|
+
* If the global process object is not suitable for instrumentation,
|
|
412
|
+
* then this will be a no-op.
|
|
413
|
+
*
|
|
414
|
+
* Returns a function that may be used to unload signal-exit.
|
|
415
|
+
*/
|
|
416
|
+
onExit} = signalExitWrap(processOk(process$1) ? new SignalExit(process$1) : new SignalExitFallback());
|
|
417
|
+
|
|
418
|
+
const escape$1 = "\x1B";
|
|
419
|
+
const pasteStart = "\x1B[200~";
|
|
420
|
+
const pasteEnd = "\x1B[201~";
|
|
421
|
+
const isCsiParameterByte = (byte) => byte >= 48 && byte <= 63;
|
|
422
|
+
const isCsiIntermediateByte = (byte) => byte >= 32 && byte <= 47;
|
|
423
|
+
const isCsiFinalByte = (byte) => byte >= 64 && byte <= 126;
|
|
424
|
+
const parseCsiSequence = (input, startIndex, prefixLength) => {
|
|
425
|
+
const csiPayloadStart = startIndex + prefixLength + 1;
|
|
426
|
+
let index = csiPayloadStart;
|
|
427
|
+
for (; index < input.length; index++) {
|
|
428
|
+
const byte = input.codePointAt(index);
|
|
429
|
+
if (byte === void 0) {
|
|
430
|
+
return "pending";
|
|
431
|
+
}
|
|
432
|
+
if (isCsiParameterByte(byte) || isCsiIntermediateByte(byte)) {
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
if (byte === 91 && index === csiPayloadStart) {
|
|
436
|
+
continue;
|
|
437
|
+
}
|
|
438
|
+
if (isCsiFinalByte(byte)) {
|
|
439
|
+
return {
|
|
440
|
+
nextIndex: index + 1,
|
|
441
|
+
sequence: input.slice(startIndex, index + 1)
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
return void 0;
|
|
445
|
+
}
|
|
446
|
+
return "pending";
|
|
447
|
+
};
|
|
448
|
+
const parseSs3Sequence = (input, startIndex, prefixLength) => {
|
|
449
|
+
const nextIndex = startIndex + prefixLength + 2;
|
|
450
|
+
if (nextIndex > input.length) {
|
|
451
|
+
return "pending";
|
|
452
|
+
}
|
|
453
|
+
const finalByte = input.codePointAt(nextIndex - 1);
|
|
454
|
+
if (finalByte === void 0 || !isCsiFinalByte(finalByte)) {
|
|
455
|
+
return void 0;
|
|
456
|
+
}
|
|
457
|
+
return {
|
|
458
|
+
nextIndex,
|
|
459
|
+
sequence: input.slice(startIndex, nextIndex)
|
|
460
|
+
};
|
|
461
|
+
};
|
|
462
|
+
const parseControlSequence = (input, startIndex, prefixLength) => {
|
|
463
|
+
const sequenceType = input[startIndex + prefixLength];
|
|
464
|
+
if (sequenceType === void 0) {
|
|
465
|
+
return "pending";
|
|
466
|
+
}
|
|
467
|
+
if (sequenceType === "[") {
|
|
468
|
+
return parseCsiSequence(input, startIndex, prefixLength);
|
|
469
|
+
}
|
|
470
|
+
if (sequenceType === "O") {
|
|
471
|
+
return parseSs3Sequence(input, startIndex, prefixLength);
|
|
472
|
+
}
|
|
473
|
+
return void 0;
|
|
474
|
+
};
|
|
475
|
+
const parseEscapedCodePoint = (input, escapeIndex) => {
|
|
476
|
+
const nextCodePoint = input.codePointAt(escapeIndex + 1);
|
|
477
|
+
const nextCodePointLength = nextCodePoint !== void 0 && nextCodePoint > 65535 ? 2 : 1;
|
|
478
|
+
const nextIndex = escapeIndex + 1 + nextCodePointLength;
|
|
479
|
+
return {
|
|
480
|
+
nextIndex,
|
|
481
|
+
sequence: input.slice(escapeIndex, nextIndex)
|
|
482
|
+
};
|
|
483
|
+
};
|
|
484
|
+
const parseEscapeSequence = (input, escapeIndex) => {
|
|
485
|
+
if (escapeIndex === input.length - 1) {
|
|
486
|
+
return "pending";
|
|
487
|
+
}
|
|
488
|
+
const next = input[escapeIndex + 1];
|
|
489
|
+
if (next === escape$1) {
|
|
490
|
+
if (escapeIndex + 2 >= input.length) {
|
|
491
|
+
return "pending";
|
|
492
|
+
}
|
|
493
|
+
const doubleEscapeSequence = parseControlSequence(input, escapeIndex, 2);
|
|
494
|
+
if (doubleEscapeSequence === "pending") {
|
|
495
|
+
return "pending";
|
|
496
|
+
}
|
|
497
|
+
if (doubleEscapeSequence) {
|
|
498
|
+
return doubleEscapeSequence;
|
|
499
|
+
}
|
|
500
|
+
return {
|
|
501
|
+
nextIndex: escapeIndex + 2,
|
|
502
|
+
sequence: input.slice(escapeIndex, escapeIndex + 2)
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
const controlSequence = parseControlSequence(input, escapeIndex, 1);
|
|
506
|
+
if (controlSequence === "pending") {
|
|
507
|
+
return "pending";
|
|
508
|
+
}
|
|
509
|
+
if (controlSequence) {
|
|
510
|
+
return controlSequence;
|
|
511
|
+
}
|
|
512
|
+
return parseEscapedCodePoint(input, escapeIndex);
|
|
513
|
+
};
|
|
514
|
+
const splitDeleteAndBackspace = (text, events) => {
|
|
515
|
+
let textSegmentStart = 0;
|
|
516
|
+
for (let index = 0; index < text.length; index++) {
|
|
517
|
+
const character = text[index];
|
|
518
|
+
if (character === "" || character === "\b") {
|
|
519
|
+
if (index > textSegmentStart) {
|
|
520
|
+
events.push(text.slice(textSegmentStart, index));
|
|
521
|
+
}
|
|
522
|
+
events.push(character);
|
|
523
|
+
textSegmentStart = index + 1;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
if (textSegmentStart < text.length) {
|
|
527
|
+
events.push(text.slice(textSegmentStart));
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
const parseKeypresses = (input) => {
|
|
531
|
+
const events = [];
|
|
532
|
+
let index = 0;
|
|
533
|
+
const pendingFrom = (pendingStartIndex) => {
|
|
534
|
+
return {
|
|
535
|
+
events,
|
|
536
|
+
pending: input.slice(pendingStartIndex)
|
|
537
|
+
};
|
|
538
|
+
};
|
|
539
|
+
while (index < input.length) {
|
|
540
|
+
const escapeIndex = input.indexOf(escape$1, index);
|
|
541
|
+
if (escapeIndex === -1) {
|
|
542
|
+
splitDeleteAndBackspace(input.slice(index), events);
|
|
543
|
+
return {
|
|
544
|
+
events,
|
|
545
|
+
pending: ""
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
if (escapeIndex > index) {
|
|
549
|
+
splitDeleteAndBackspace(input.slice(index, escapeIndex), events);
|
|
550
|
+
}
|
|
551
|
+
const parsedEscapeSequence = parseEscapeSequence(input, escapeIndex);
|
|
552
|
+
if (parsedEscapeSequence === "pending") {
|
|
553
|
+
return pendingFrom(escapeIndex);
|
|
554
|
+
}
|
|
555
|
+
if (parsedEscapeSequence.sequence === pasteStart) {
|
|
556
|
+
const afterStart = parsedEscapeSequence.nextIndex;
|
|
557
|
+
const endIndex = input.indexOf(pasteEnd, afterStart);
|
|
558
|
+
if (endIndex === -1) {
|
|
559
|
+
return pendingFrom(escapeIndex);
|
|
560
|
+
}
|
|
561
|
+
events.push({ paste: input.slice(afterStart, endIndex) });
|
|
562
|
+
index = endIndex + pasteEnd.length;
|
|
563
|
+
continue;
|
|
564
|
+
}
|
|
565
|
+
events.push(parsedEscapeSequence.sequence);
|
|
566
|
+
index = parsedEscapeSequence.nextIndex;
|
|
567
|
+
}
|
|
568
|
+
return {
|
|
569
|
+
events,
|
|
570
|
+
pending: ""
|
|
571
|
+
};
|
|
572
|
+
};
|
|
573
|
+
const createInputParser = () => {
|
|
574
|
+
let pending = "";
|
|
575
|
+
return {
|
|
576
|
+
flushPendingEscape() {
|
|
577
|
+
if (!pending.startsWith(escape$1)) {
|
|
578
|
+
return void 0;
|
|
579
|
+
}
|
|
580
|
+
const pendingEscape = pending;
|
|
581
|
+
pending = "";
|
|
582
|
+
return pendingEscape;
|
|
583
|
+
},
|
|
584
|
+
hasPendingEscape() {
|
|
585
|
+
return pending.startsWith(escape$1) && !pending.startsWith(pasteStart) && pending !== "\x1B[200";
|
|
586
|
+
},
|
|
587
|
+
push(chunk) {
|
|
588
|
+
const parsedInput = parseKeypresses(pending + chunk);
|
|
589
|
+
pending = parsedInput.pending;
|
|
590
|
+
return parsedInput.events;
|
|
591
|
+
},
|
|
592
|
+
reset() {
|
|
593
|
+
pending = "";
|
|
594
|
+
}
|
|
595
|
+
};
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
const convertToSpaces = (input, spaces = 2) => {
|
|
599
|
+
return input.replace(/^\t+/gm, ($1) => " ".repeat($1.length * spaces));
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
const generateLineNumbers = (line, around) => {
|
|
603
|
+
const lineNumbers = [];
|
|
604
|
+
const min = line - around;
|
|
605
|
+
const max = line + around;
|
|
606
|
+
for (let lineNumber = min; lineNumber <= max; lineNumber++) {
|
|
607
|
+
lineNumbers.push(lineNumber);
|
|
608
|
+
}
|
|
609
|
+
return lineNumbers;
|
|
610
|
+
};
|
|
611
|
+
const codeExcerpt = (source, line, options = {}) => {
|
|
612
|
+
var _a;
|
|
613
|
+
if (typeof source !== "string") {
|
|
614
|
+
throw new TypeError("Source code is missing.");
|
|
615
|
+
}
|
|
616
|
+
if (!line || line < 1) {
|
|
617
|
+
throw new TypeError("Line number must start from `1`.");
|
|
618
|
+
}
|
|
619
|
+
const lines = convertToSpaces(source).split(/\r?\n/);
|
|
620
|
+
if (line > lines.length) {
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
return generateLineNumbers(line, (_a = options.around) !== null && _a !== void 0 ? _a : 3).filter((line2) => lines[line2 - 1] !== void 0).map((line2) => ({ line: line2, value: lines[line2 - 1] }));
|
|
624
|
+
};
|
|
625
|
+
|
|
626
|
+
function getDefaultExportFromCjs(x) {
|
|
627
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
var escapeStringRegexp;
|
|
631
|
+
var hasRequiredEscapeStringRegexp;
|
|
632
|
+
|
|
633
|
+
function requireEscapeStringRegexp () {
|
|
634
|
+
if (hasRequiredEscapeStringRegexp) return escapeStringRegexp;
|
|
635
|
+
hasRequiredEscapeStringRegexp = 1;
|
|
636
|
+
const matchOperatorsRegex = /[|\\{}()[\]^$+*?.-]/g;
|
|
637
|
+
escapeStringRegexp = (string) => {
|
|
638
|
+
if (typeof string !== "string") {
|
|
639
|
+
throw new TypeError("Expected a string");
|
|
640
|
+
}
|
|
641
|
+
return string.replace(matchOperatorsRegex, "\\$&");
|
|
642
|
+
};
|
|
643
|
+
return escapeStringRegexp;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
var stackUtils$1;
|
|
647
|
+
var hasRequiredStackUtils;
|
|
648
|
+
|
|
649
|
+
function requireStackUtils () {
|
|
650
|
+
if (hasRequiredStackUtils) return stackUtils$1;
|
|
651
|
+
hasRequiredStackUtils = 1;
|
|
652
|
+
const escapeStringRegexp = requireEscapeStringRegexp();
|
|
653
|
+
const cwd = process && typeof process.cwd === "function" ? process.cwd() : ".";
|
|
654
|
+
const natives = [].concat(
|
|
655
|
+
require$$1.builtinModules,
|
|
656
|
+
"bootstrap_node",
|
|
657
|
+
"node"
|
|
658
|
+
).map((n) => new RegExp(`(?:\\((?:node:)?${n}(?:\\.js)?:\\d+:\\d+\\)$|^\\s*at (?:node:)?${n}(?:\\.js)?:\\d+:\\d+$)`));
|
|
659
|
+
natives.push(
|
|
660
|
+
/\((?:node:)?internal\/[^:]+:\d+:\d+\)$/,
|
|
661
|
+
/\s*at (?:node:)?internal\/[^:]+:\d+:\d+$/,
|
|
662
|
+
/\/\.node-spawn-wrap-\w+-\w+\/node:\d+:\d+\)?$/
|
|
663
|
+
);
|
|
664
|
+
class StackUtils {
|
|
665
|
+
constructor(opts) {
|
|
666
|
+
opts = {
|
|
667
|
+
ignoredPackages: [],
|
|
668
|
+
...opts
|
|
669
|
+
};
|
|
670
|
+
if ("internals" in opts === false) {
|
|
671
|
+
opts.internals = StackUtils.nodeInternals();
|
|
672
|
+
}
|
|
673
|
+
if ("cwd" in opts === false) {
|
|
674
|
+
opts.cwd = cwd;
|
|
675
|
+
}
|
|
676
|
+
this._cwd = opts.cwd.replace(/\\/g, "/");
|
|
677
|
+
this._internals = [].concat(
|
|
678
|
+
opts.internals,
|
|
679
|
+
ignoredPackagesRegExp(opts.ignoredPackages)
|
|
680
|
+
);
|
|
681
|
+
this._wrapCallSite = opts.wrapCallSite || false;
|
|
682
|
+
}
|
|
683
|
+
static nodeInternals() {
|
|
684
|
+
return [...natives];
|
|
685
|
+
}
|
|
686
|
+
clean(stack, indent = 0) {
|
|
687
|
+
indent = " ".repeat(indent);
|
|
688
|
+
if (!Array.isArray(stack)) {
|
|
689
|
+
stack = stack.split("\n");
|
|
690
|
+
}
|
|
691
|
+
if (!/^\s*at /.test(stack[0]) && /^\s*at /.test(stack[1])) {
|
|
692
|
+
stack = stack.slice(1);
|
|
693
|
+
}
|
|
694
|
+
let outdent = false;
|
|
695
|
+
let lastNonAtLine = null;
|
|
696
|
+
const result = [];
|
|
697
|
+
stack.forEach((st) => {
|
|
698
|
+
st = st.replace(/\\/g, "/");
|
|
699
|
+
if (this._internals.some((internal) => internal.test(st))) {
|
|
700
|
+
return;
|
|
701
|
+
}
|
|
702
|
+
const isAtLine = /^\s*at /.test(st);
|
|
703
|
+
if (outdent) {
|
|
704
|
+
st = st.trimEnd().replace(/^(\s+)at /, "$1");
|
|
705
|
+
} else {
|
|
706
|
+
st = st.trim();
|
|
707
|
+
if (isAtLine) {
|
|
708
|
+
st = st.slice(3);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
st = st.replace(`${this._cwd}/`, "");
|
|
712
|
+
if (st) {
|
|
713
|
+
if (isAtLine) {
|
|
714
|
+
if (lastNonAtLine) {
|
|
715
|
+
result.push(lastNonAtLine);
|
|
716
|
+
lastNonAtLine = null;
|
|
717
|
+
}
|
|
718
|
+
result.push(st);
|
|
719
|
+
} else {
|
|
720
|
+
outdent = true;
|
|
721
|
+
lastNonAtLine = st;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
return result.map((line) => `${indent}${line}
|
|
726
|
+
`).join("");
|
|
727
|
+
}
|
|
728
|
+
captureString(limit, fn = this.captureString) {
|
|
729
|
+
if (typeof limit === "function") {
|
|
730
|
+
fn = limit;
|
|
731
|
+
limit = Infinity;
|
|
732
|
+
}
|
|
733
|
+
const { stackTraceLimit } = Error;
|
|
734
|
+
if (limit) {
|
|
735
|
+
Error.stackTraceLimit = limit;
|
|
736
|
+
}
|
|
737
|
+
const obj = {};
|
|
738
|
+
Error.captureStackTrace(obj, fn);
|
|
739
|
+
const { stack } = obj;
|
|
740
|
+
Error.stackTraceLimit = stackTraceLimit;
|
|
741
|
+
return this.clean(stack);
|
|
742
|
+
}
|
|
743
|
+
capture(limit, fn = this.capture) {
|
|
744
|
+
if (typeof limit === "function") {
|
|
745
|
+
fn = limit;
|
|
746
|
+
limit = Infinity;
|
|
747
|
+
}
|
|
748
|
+
const { prepareStackTrace, stackTraceLimit } = Error;
|
|
749
|
+
Error.prepareStackTrace = (obj2, site) => {
|
|
750
|
+
if (this._wrapCallSite) {
|
|
751
|
+
return site.map(this._wrapCallSite);
|
|
752
|
+
}
|
|
753
|
+
return site;
|
|
754
|
+
};
|
|
755
|
+
if (limit) {
|
|
756
|
+
Error.stackTraceLimit = limit;
|
|
757
|
+
}
|
|
758
|
+
const obj = {};
|
|
759
|
+
Error.captureStackTrace(obj, fn);
|
|
760
|
+
const { stack } = obj;
|
|
761
|
+
Object.assign(Error, { prepareStackTrace, stackTraceLimit });
|
|
762
|
+
return stack;
|
|
763
|
+
}
|
|
764
|
+
at(fn = this.at) {
|
|
765
|
+
const [site] = this.capture(1, fn);
|
|
766
|
+
if (!site) {
|
|
767
|
+
return {};
|
|
768
|
+
}
|
|
769
|
+
const res = {
|
|
770
|
+
line: site.getLineNumber(),
|
|
771
|
+
column: site.getColumnNumber()
|
|
772
|
+
};
|
|
773
|
+
setFile(res, site.getFileName(), this._cwd);
|
|
774
|
+
if (site.isConstructor()) {
|
|
775
|
+
Object.defineProperty(res, "constructor", {
|
|
776
|
+
value: true,
|
|
777
|
+
configurable: true
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
if (site.isEval()) {
|
|
781
|
+
res.evalOrigin = site.getEvalOrigin();
|
|
782
|
+
}
|
|
783
|
+
if (site.isNative()) {
|
|
784
|
+
res.native = true;
|
|
785
|
+
}
|
|
786
|
+
let typename;
|
|
787
|
+
try {
|
|
788
|
+
typename = site.getTypeName();
|
|
789
|
+
} catch (_) {
|
|
790
|
+
}
|
|
791
|
+
if (typename && typename !== "Object" && typename !== "[object Object]") {
|
|
792
|
+
res.type = typename;
|
|
793
|
+
}
|
|
794
|
+
const fname = site.getFunctionName();
|
|
795
|
+
if (fname) {
|
|
796
|
+
res.function = fname;
|
|
797
|
+
}
|
|
798
|
+
const meth = site.getMethodName();
|
|
799
|
+
if (meth && fname !== meth) {
|
|
800
|
+
res.method = meth;
|
|
801
|
+
}
|
|
802
|
+
return res;
|
|
803
|
+
}
|
|
804
|
+
parseLine(line) {
|
|
805
|
+
const match = line && line.match(re);
|
|
806
|
+
if (!match) {
|
|
807
|
+
return null;
|
|
808
|
+
}
|
|
809
|
+
const ctor = match[1] === "new";
|
|
810
|
+
let fname = match[2];
|
|
811
|
+
const evalOrigin = match[3];
|
|
812
|
+
const evalFile = match[4];
|
|
813
|
+
const evalLine = Number(match[5]);
|
|
814
|
+
const evalCol = Number(match[6]);
|
|
815
|
+
let file = match[7];
|
|
816
|
+
const lnum = match[8];
|
|
817
|
+
const col = match[9];
|
|
818
|
+
const native = match[10] === "native";
|
|
819
|
+
const closeParen = match[11] === ")";
|
|
820
|
+
let method;
|
|
821
|
+
const res = {};
|
|
822
|
+
if (lnum) {
|
|
823
|
+
res.line = Number(lnum);
|
|
824
|
+
}
|
|
825
|
+
if (col) {
|
|
826
|
+
res.column = Number(col);
|
|
827
|
+
}
|
|
828
|
+
if (closeParen && file) {
|
|
829
|
+
let closes = 0;
|
|
830
|
+
for (let i = file.length - 1; i > 0; i--) {
|
|
831
|
+
if (file.charAt(i) === ")") {
|
|
832
|
+
closes++;
|
|
833
|
+
} else if (file.charAt(i) === "(" && file.charAt(i - 1) === " ") {
|
|
834
|
+
closes--;
|
|
835
|
+
if (closes === -1 && file.charAt(i - 1) === " ") {
|
|
836
|
+
const before = file.slice(0, i - 1);
|
|
837
|
+
const after = file.slice(i + 1);
|
|
838
|
+
file = after;
|
|
839
|
+
fname += ` (${before}`;
|
|
840
|
+
break;
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
if (fname) {
|
|
846
|
+
const methodMatch = fname.match(methodRe);
|
|
847
|
+
if (methodMatch) {
|
|
848
|
+
fname = methodMatch[1];
|
|
849
|
+
method = methodMatch[2];
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
setFile(res, file, this._cwd);
|
|
853
|
+
if (ctor) {
|
|
854
|
+
Object.defineProperty(res, "constructor", {
|
|
855
|
+
value: true,
|
|
856
|
+
configurable: true
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
if (evalOrigin) {
|
|
860
|
+
res.evalOrigin = evalOrigin;
|
|
861
|
+
res.evalLine = evalLine;
|
|
862
|
+
res.evalColumn = evalCol;
|
|
863
|
+
res.evalFile = evalFile && evalFile.replace(/\\/g, "/");
|
|
864
|
+
}
|
|
865
|
+
if (native) {
|
|
866
|
+
res.native = true;
|
|
867
|
+
}
|
|
868
|
+
if (fname) {
|
|
869
|
+
res.function = fname;
|
|
870
|
+
}
|
|
871
|
+
if (method && fname !== method) {
|
|
872
|
+
res.method = method;
|
|
873
|
+
}
|
|
874
|
+
return res;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
function setFile(result, filename, cwd2) {
|
|
878
|
+
if (filename) {
|
|
879
|
+
filename = filename.replace(/\\/g, "/");
|
|
880
|
+
if (filename.startsWith(`${cwd2}/`)) {
|
|
881
|
+
filename = filename.slice(cwd2.length + 1);
|
|
882
|
+
}
|
|
883
|
+
result.file = filename;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
function ignoredPackagesRegExp(ignoredPackages) {
|
|
887
|
+
if (ignoredPackages.length === 0) {
|
|
888
|
+
return [];
|
|
889
|
+
}
|
|
890
|
+
const packages = ignoredPackages.map((mod) => escapeStringRegexp(mod));
|
|
891
|
+
return new RegExp(`[/\\\\]node_modules[/\\\\](?:${packages.join("|")})[/\\\\][^:]+:\\d+:\\d+`);
|
|
892
|
+
}
|
|
893
|
+
const re = new RegExp(
|
|
894
|
+
"^(?:\\s*at )?(?:(new) )?(?:(.*?) \\()?(?:eval at ([^ ]+) \\((.+?):(\\d+):(\\d+)\\), )?(?:(.+?):(\\d+):(\\d+)|(native))(\\)?)$"
|
|
895
|
+
);
|
|
896
|
+
const methodRe = /^(.*?) \[as (.*?)\]$/;
|
|
897
|
+
stackUtils$1 = StackUtils;
|
|
898
|
+
return stackUtils$1;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
var stackUtilsExports = requireStackUtils();
|
|
902
|
+
const StackUtils = /*@__PURE__*/getDefaultExportFromCjs(stackUtilsExports);
|
|
903
|
+
|
|
904
|
+
const cleanupPath = (path) => path?.replace(`file://${cwd()}/`, "");
|
|
905
|
+
const stackUtils = new StackUtils({
|
|
906
|
+
cwd: cwd(),
|
|
907
|
+
internals: StackUtils.nodeInternals()
|
|
908
|
+
});
|
|
909
|
+
function ErrorOverview({ error }) {
|
|
910
|
+
const stack = error.stack ? error.stack.split("\n").slice(1) : void 0;
|
|
911
|
+
const origin = stack ? stackUtils.parseLine(stack[0]) : void 0;
|
|
912
|
+
const filePath = cleanupPath(origin?.file);
|
|
913
|
+
let excerpt;
|
|
914
|
+
let lineWidth = 0;
|
|
915
|
+
if (filePath && origin?.line && existsSync(filePath)) {
|
|
916
|
+
const sourceCode = readFileSync(filePath, "utf8");
|
|
917
|
+
excerpt = codeExcerpt(sourceCode, origin.line);
|
|
918
|
+
if (excerpt) {
|
|
919
|
+
for (const { line } of excerpt) {
|
|
920
|
+
lineWidth = Math.max(lineWidth, String(line).length);
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
return jsxs(Box, { flexDirection: "column", padding: 1, children: [
|
|
925
|
+
jsxs(Box, { children: [
|
|
926
|
+
jsxs(Text, { backgroundColor: "red", color: "white", children: [
|
|
927
|
+
" ",
|
|
928
|
+
"ERROR",
|
|
929
|
+
" "
|
|
930
|
+
] }),
|
|
931
|
+
jsxs(Text, { children: [
|
|
932
|
+
" ",
|
|
933
|
+
error.message
|
|
934
|
+
] })
|
|
935
|
+
] }),
|
|
936
|
+
origin && filePath ? jsx(Box, { marginTop: 1, children: jsxs(Text, { dimColor: true, children: [
|
|
937
|
+
filePath,
|
|
938
|
+
":",
|
|
939
|
+
origin.line,
|
|
940
|
+
":",
|
|
941
|
+
origin.column
|
|
942
|
+
] }) }) : null,
|
|
943
|
+
origin && excerpt ? jsx(Box, { flexDirection: "column", marginTop: 1, children: excerpt.map(({ line, value }) => jsxs(Box, { children: [
|
|
944
|
+
jsx(Box, { width: lineWidth + 1, children: jsxs(
|
|
945
|
+
Text,
|
|
946
|
+
{
|
|
947
|
+
"aria-label": line === origin.line ? `Line ${line}, error` : `Line ${line}`,
|
|
948
|
+
backgroundColor: line === origin.line ? "red" : void 0,
|
|
949
|
+
color: line === origin.line ? "white" : void 0,
|
|
950
|
+
dimColor: line !== origin.line,
|
|
951
|
+
children: [
|
|
952
|
+
String(line).padStart(lineWidth, " "),
|
|
953
|
+
":"
|
|
954
|
+
]
|
|
955
|
+
}
|
|
956
|
+
) }),
|
|
957
|
+
jsx(Text, { backgroundColor: line === origin.line ? "red" : void 0, color: line === origin.line ? "white" : void 0, children: ` ${value}` }, line)
|
|
958
|
+
] }, line)) }) : null,
|
|
959
|
+
stack ? jsx(Box, { flexDirection: "column", marginTop: 1, children: stack.map((line) => {
|
|
960
|
+
const parsedLine = stackUtils.parseLine(line);
|
|
961
|
+
if (!parsedLine) {
|
|
962
|
+
return jsxs(Box, { children: [
|
|
963
|
+
jsx(Text, { dimColor: true, children: "- " }),
|
|
964
|
+
jsxs(Text, { bold: true, dimColor: true, children: [
|
|
965
|
+
line,
|
|
966
|
+
"\\t",
|
|
967
|
+
" "
|
|
968
|
+
] })
|
|
969
|
+
] }, line);
|
|
970
|
+
}
|
|
971
|
+
return jsxs(Box, { children: [
|
|
972
|
+
jsx(Text, { dimColor: true, children: "- " }),
|
|
973
|
+
jsx(Text, { bold: true, dimColor: true, children: parsedLine.function }),
|
|
974
|
+
jsxs(
|
|
975
|
+
Text,
|
|
976
|
+
{
|
|
977
|
+
"aria-label": `at ${cleanupPath(parsedLine.file) ?? ""} line ${parsedLine.line} column ${parsedLine.column}`,
|
|
978
|
+
color: "gray",
|
|
979
|
+
dimColor: true,
|
|
980
|
+
children: [
|
|
981
|
+
" ",
|
|
982
|
+
"(",
|
|
983
|
+
cleanupPath(parsedLine.file) ?? "",
|
|
984
|
+
":",
|
|
985
|
+
parsedLine.line,
|
|
986
|
+
":",
|
|
987
|
+
parsedLine.column,
|
|
988
|
+
")"
|
|
989
|
+
]
|
|
990
|
+
}
|
|
991
|
+
)
|
|
992
|
+
] }, line);
|
|
993
|
+
}) }) : null
|
|
994
|
+
] });
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
class ErrorBoundary extends PureComponent {
|
|
998
|
+
static displayName = "InternalErrorBoundary";
|
|
999
|
+
static getDerivedStateFromError(error) {
|
|
1000
|
+
return { error };
|
|
1001
|
+
}
|
|
1002
|
+
state = {
|
|
1003
|
+
error: void 0
|
|
1004
|
+
};
|
|
1005
|
+
componentDidCatch(error) {
|
|
1006
|
+
this.props.onError(error);
|
|
1007
|
+
}
|
|
1008
|
+
render() {
|
|
1009
|
+
if (this.state.error) {
|
|
1010
|
+
return jsx(ErrorOverview, { error: this.state.error });
|
|
1011
|
+
}
|
|
1012
|
+
return this.props.children;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
const tab = " ";
|
|
1017
|
+
const shiftTab = "\x1B[Z";
|
|
1018
|
+
const escape = "\x1B";
|
|
1019
|
+
const App = ({
|
|
1020
|
+
children,
|
|
1021
|
+
exitOnCtrlC,
|
|
1022
|
+
interactive,
|
|
1023
|
+
onExit,
|
|
1024
|
+
onWaitUntilRenderFlush,
|
|
1025
|
+
renderThrottleMs,
|
|
1026
|
+
setCursorPosition,
|
|
1027
|
+
stderr,
|
|
1028
|
+
stdin,
|
|
1029
|
+
stdout,
|
|
1030
|
+
writeToStderr,
|
|
1031
|
+
writeToStdout
|
|
1032
|
+
}) => {
|
|
1033
|
+
const [isFocusEnabled, setIsFocusEnabled] = useState(true);
|
|
1034
|
+
const [activeFocusId, setActiveFocusId] = useState(void 0);
|
|
1035
|
+
const [, setFocusables] = useState([]);
|
|
1036
|
+
const focusablesCountRef = useRef(0);
|
|
1037
|
+
const animationSubscribersRef = useRef(/* @__PURE__ */ new Map());
|
|
1038
|
+
const animationTimerRef = useRef(void 0);
|
|
1039
|
+
const rawModeEnabledCount = useRef(0);
|
|
1040
|
+
const bracketedPasteModeEnabledCount = useRef(0);
|
|
1041
|
+
const [internal_eventEmitter] = useState(() => {
|
|
1042
|
+
const emitter = new EventEmitter();
|
|
1043
|
+
emitter.setMaxListeners(Infinity);
|
|
1044
|
+
return emitter;
|
|
1045
|
+
});
|
|
1046
|
+
const readableListenerRef = useRef(void 0);
|
|
1047
|
+
const inputParserRef = useRef(void 0);
|
|
1048
|
+
inputParserRef.current ??= createInputParser();
|
|
1049
|
+
const pendingInputFlushRef = useRef(void 0);
|
|
1050
|
+
const didWarnAboutDeprecatedPasteFallbackRef = useRef(false);
|
|
1051
|
+
const pendingInputFlushDelayMilliseconds = 20;
|
|
1052
|
+
const clearPendingInputFlush = useCallback(() => {
|
|
1053
|
+
if (!pendingInputFlushRef.current) {
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1056
|
+
clearTimeout(pendingInputFlushRef.current);
|
|
1057
|
+
pendingInputFlushRef.current = void 0;
|
|
1058
|
+
}, []);
|
|
1059
|
+
const clearAnimationTimer = useCallback(() => {
|
|
1060
|
+
if (!animationTimerRef.current) {
|
|
1061
|
+
return;
|
|
1062
|
+
}
|
|
1063
|
+
clearTimeout(animationTimerRef.current);
|
|
1064
|
+
animationTimerRef.current = void 0;
|
|
1065
|
+
}, []);
|
|
1066
|
+
const scheduleAnimationTick = useCallback(() => {
|
|
1067
|
+
clearAnimationTimer();
|
|
1068
|
+
if (animationSubscribersRef.current.size === 0) {
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
let nextDueTime = Number.POSITIVE_INFINITY;
|
|
1072
|
+
for (const subscriber of animationSubscribersRef.current.values()) {
|
|
1073
|
+
nextDueTime = Math.min(nextDueTime, subscriber.nextDueTime);
|
|
1074
|
+
}
|
|
1075
|
+
const delay = Math.max(0, nextDueTime - performance.now());
|
|
1076
|
+
animationTimerRef.current = setTimeout(() => {
|
|
1077
|
+
animationTimerRef.current = void 0;
|
|
1078
|
+
const currentTime = performance.now();
|
|
1079
|
+
const subscribers = [...animationSubscribersRef.current.values()];
|
|
1080
|
+
for (const subscriber of subscribers) {
|
|
1081
|
+
if (currentTime < subscriber.nextDueTime) {
|
|
1082
|
+
continue;
|
|
1083
|
+
}
|
|
1084
|
+
subscriber.callback(currentTime);
|
|
1085
|
+
const elapsedTime = currentTime - subscriber.startTime;
|
|
1086
|
+
const elapsedFrames = Math.floor(elapsedTime / subscriber.interval) + 1;
|
|
1087
|
+
subscriber.nextDueTime = subscriber.startTime + elapsedFrames * subscriber.interval;
|
|
1088
|
+
}
|
|
1089
|
+
scheduleAnimationTick();
|
|
1090
|
+
}, delay);
|
|
1091
|
+
}, [clearAnimationTimer]);
|
|
1092
|
+
const animationSubscribe = useCallback(
|
|
1093
|
+
(callback, interval) => {
|
|
1094
|
+
const startTime = performance.now();
|
|
1095
|
+
animationSubscribersRef.current.set(callback, {
|
|
1096
|
+
callback,
|
|
1097
|
+
interval,
|
|
1098
|
+
nextDueTime: startTime + interval,
|
|
1099
|
+
startTime
|
|
1100
|
+
});
|
|
1101
|
+
scheduleAnimationTick();
|
|
1102
|
+
return {
|
|
1103
|
+
startTime,
|
|
1104
|
+
unsubscribe() {
|
|
1105
|
+
animationSubscribersRef.current.delete(callback);
|
|
1106
|
+
if (animationSubscribersRef.current.size === 0) {
|
|
1107
|
+
clearAnimationTimer();
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
scheduleAnimationTick();
|
|
1111
|
+
}
|
|
1112
|
+
};
|
|
1113
|
+
},
|
|
1114
|
+
[clearAnimationTimer, scheduleAnimationTick]
|
|
1115
|
+
);
|
|
1116
|
+
useEffect(() => {
|
|
1117
|
+
return () => {
|
|
1118
|
+
clearAnimationTimer();
|
|
1119
|
+
};
|
|
1120
|
+
}, [clearAnimationTimer]);
|
|
1121
|
+
const isRawModeSupported = stdin.isTTY;
|
|
1122
|
+
const detachReadableListener = useCallback(() => {
|
|
1123
|
+
if (!readableListenerRef.current) {
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1126
|
+
stdin.removeListener("readable", readableListenerRef.current);
|
|
1127
|
+
readableListenerRef.current = void 0;
|
|
1128
|
+
}, [stdin]);
|
|
1129
|
+
const disableRawMode = useCallback(() => {
|
|
1130
|
+
stdin.setRawMode(false);
|
|
1131
|
+
detachReadableListener();
|
|
1132
|
+
stdin.unref();
|
|
1133
|
+
rawModeEnabledCount.current = 0;
|
|
1134
|
+
inputParserRef.current?.reset();
|
|
1135
|
+
clearPendingInputFlush();
|
|
1136
|
+
}, [stdin, detachReadableListener, clearPendingInputFlush]);
|
|
1137
|
+
const handleExit = useCallback(
|
|
1138
|
+
(errorOrResult) => {
|
|
1139
|
+
if (isRawModeSupported && rawModeEnabledCount.current > 0) {
|
|
1140
|
+
disableRawMode();
|
|
1141
|
+
}
|
|
1142
|
+
onExit(errorOrResult);
|
|
1143
|
+
},
|
|
1144
|
+
[isRawModeSupported, disableRawMode, onExit]
|
|
1145
|
+
);
|
|
1146
|
+
const handleInput = useCallback(
|
|
1147
|
+
(input) => {
|
|
1148
|
+
if (input.includes("") && exitOnCtrlC) {
|
|
1149
|
+
handleExit();
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
if (input === escape) {
|
|
1153
|
+
setActiveFocusId((currentActiveFocusId) => {
|
|
1154
|
+
if (currentActiveFocusId) {
|
|
1155
|
+
return void 0;
|
|
1156
|
+
}
|
|
1157
|
+
return currentActiveFocusId;
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
},
|
|
1161
|
+
[exitOnCtrlC, handleExit]
|
|
1162
|
+
);
|
|
1163
|
+
const emitInput = useCallback(
|
|
1164
|
+
(input) => {
|
|
1165
|
+
handleInput(input);
|
|
1166
|
+
internal_eventEmitter.emit("input", input);
|
|
1167
|
+
},
|
|
1168
|
+
[handleInput, internal_eventEmitter]
|
|
1169
|
+
);
|
|
1170
|
+
const schedulePendingInputFlush = useCallback(() => {
|
|
1171
|
+
clearPendingInputFlush();
|
|
1172
|
+
pendingInputFlushRef.current = setTimeout(() => {
|
|
1173
|
+
pendingInputFlushRef.current = void 0;
|
|
1174
|
+
const pendingEscape = inputParserRef.current.flushPendingEscape();
|
|
1175
|
+
if (!pendingEscape) {
|
|
1176
|
+
return;
|
|
1177
|
+
}
|
|
1178
|
+
emitInput(pendingEscape);
|
|
1179
|
+
}, pendingInputFlushDelayMilliseconds);
|
|
1180
|
+
}, [clearPendingInputFlush, emitInput]);
|
|
1181
|
+
const handleReadable = useCallback(() => {
|
|
1182
|
+
clearPendingInputFlush();
|
|
1183
|
+
let chunk;
|
|
1184
|
+
while ((chunk = stdin.read()) !== null) {
|
|
1185
|
+
const inputEvents = inputParserRef.current.push(chunk);
|
|
1186
|
+
for (const event of inputEvents) {
|
|
1187
|
+
if (typeof event === "string") {
|
|
1188
|
+
emitInput(event);
|
|
1189
|
+
} else {
|
|
1190
|
+
if (internal_eventEmitter.listenerCount("paste") === 0) {
|
|
1191
|
+
if (!didWarnAboutDeprecatedPasteFallbackRef.current) {
|
|
1192
|
+
didWarnAboutDeprecatedPasteFallbackRef.current = true;
|
|
1193
|
+
writeToStderr(
|
|
1194
|
+
"Warning: useInput() received bracketed paste because no usePaste() handler is active. This fallback is deprecated and will be removed in the next major version. Migrate paste handling to usePaste().\n"
|
|
1195
|
+
);
|
|
1196
|
+
}
|
|
1197
|
+
emitInput(event.paste);
|
|
1198
|
+
continue;
|
|
1199
|
+
}
|
|
1200
|
+
internal_eventEmitter.emit("paste", event.paste);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
if (inputParserRef.current.hasPendingEscape()) {
|
|
1205
|
+
schedulePendingInputFlush();
|
|
1206
|
+
}
|
|
1207
|
+
}, [stdin, emitInput, clearPendingInputFlush, schedulePendingInputFlush, writeToStderr, internal_eventEmitter]);
|
|
1208
|
+
const handleSetRawMode = useCallback(
|
|
1209
|
+
(isEnabled) => {
|
|
1210
|
+
if (!isRawModeSupported) {
|
|
1211
|
+
if (stdin === process$2.stdin) {
|
|
1212
|
+
throw new Error(
|
|
1213
|
+
"Raw mode is not supported on the current process.stdin, which Ink uses as input stream by default.\nRead about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported"
|
|
1214
|
+
);
|
|
1215
|
+
} else {
|
|
1216
|
+
throw new Error(
|
|
1217
|
+
"Raw mode is not supported on the stdin provided to Ink.\nRead about how to prevent this error on https://github.com/vadimdemedes/ink/#israwmodesupported"
|
|
1218
|
+
);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
stdin.setEncoding("utf8");
|
|
1222
|
+
if (isEnabled) {
|
|
1223
|
+
if (rawModeEnabledCount.current === 0) {
|
|
1224
|
+
stdin.ref();
|
|
1225
|
+
stdin.setRawMode(true);
|
|
1226
|
+
readableListenerRef.current = handleReadable;
|
|
1227
|
+
stdin.addListener("readable", handleReadable);
|
|
1228
|
+
}
|
|
1229
|
+
rawModeEnabledCount.current++;
|
|
1230
|
+
return;
|
|
1231
|
+
}
|
|
1232
|
+
if (rawModeEnabledCount.current === 0) {
|
|
1233
|
+
return;
|
|
1234
|
+
}
|
|
1235
|
+
if (--rawModeEnabledCount.current === 0) {
|
|
1236
|
+
disableRawMode();
|
|
1237
|
+
}
|
|
1238
|
+
},
|
|
1239
|
+
[isRawModeSupported, stdin, handleReadable, disableRawMode]
|
|
1240
|
+
);
|
|
1241
|
+
const handleSetBracketedPasteMode = useCallback(
|
|
1242
|
+
(isEnabled) => {
|
|
1243
|
+
if (!stdout.isTTY) {
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
if (isEnabled) {
|
|
1247
|
+
if (bracketedPasteModeEnabledCount.current === 0) {
|
|
1248
|
+
stdout.write("\x1B[?2004h");
|
|
1249
|
+
}
|
|
1250
|
+
bracketedPasteModeEnabledCount.current++;
|
|
1251
|
+
return;
|
|
1252
|
+
}
|
|
1253
|
+
if (bracketedPasteModeEnabledCount.current === 0) {
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
if (--bracketedPasteModeEnabledCount.current === 0) {
|
|
1257
|
+
stdout.write("\x1B[?2004l");
|
|
1258
|
+
}
|
|
1259
|
+
},
|
|
1260
|
+
[stdout]
|
|
1261
|
+
);
|
|
1262
|
+
const findNextFocusable = useCallback((currentFocusables, currentActiveFocusId) => {
|
|
1263
|
+
const activeIndex = currentFocusables.findIndex((focusable) => focusable.id === currentActiveFocusId);
|
|
1264
|
+
for (let index = activeIndex + 1; index < currentFocusables.length; index++) {
|
|
1265
|
+
const focusable = currentFocusables[index];
|
|
1266
|
+
if (focusable?.isActive) {
|
|
1267
|
+
return focusable.id;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
return void 0;
|
|
1271
|
+
}, []);
|
|
1272
|
+
const findPreviousFocusable = useCallback((currentFocusables, currentActiveFocusId) => {
|
|
1273
|
+
const activeIndex = currentFocusables.findIndex((focusable) => focusable.id === currentActiveFocusId);
|
|
1274
|
+
for (let index = activeIndex - 1; index >= 0; index--) {
|
|
1275
|
+
const focusable = currentFocusables[index];
|
|
1276
|
+
if (focusable?.isActive) {
|
|
1277
|
+
return focusable.id;
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
return void 0;
|
|
1281
|
+
}, []);
|
|
1282
|
+
const focusNext = useCallback(() => {
|
|
1283
|
+
setFocusables((currentFocusables) => {
|
|
1284
|
+
setActiveFocusId((currentActiveFocusId) => {
|
|
1285
|
+
const firstFocusableId = currentFocusables.find((focusable) => focusable.isActive)?.id;
|
|
1286
|
+
const nextFocusableId = findNextFocusable(currentFocusables, currentActiveFocusId);
|
|
1287
|
+
return nextFocusableId ?? firstFocusableId;
|
|
1288
|
+
});
|
|
1289
|
+
return currentFocusables;
|
|
1290
|
+
});
|
|
1291
|
+
}, [findNextFocusable]);
|
|
1292
|
+
const focusPrevious = useCallback(() => {
|
|
1293
|
+
setFocusables((currentFocusables) => {
|
|
1294
|
+
setActiveFocusId((currentActiveFocusId) => {
|
|
1295
|
+
const lastFocusableId = currentFocusables.findLast((focusable) => focusable.isActive)?.id;
|
|
1296
|
+
const previousFocusableId = findPreviousFocusable(currentFocusables, currentActiveFocusId);
|
|
1297
|
+
return previousFocusableId ?? lastFocusableId;
|
|
1298
|
+
});
|
|
1299
|
+
return currentFocusables;
|
|
1300
|
+
});
|
|
1301
|
+
}, [findPreviousFocusable]);
|
|
1302
|
+
useEffect(() => {
|
|
1303
|
+
const handleTabNavigation = (input) => {
|
|
1304
|
+
if (!isFocusEnabled || focusablesCountRef.current === 0) {
|
|
1305
|
+
return;
|
|
1306
|
+
}
|
|
1307
|
+
if (input === tab) {
|
|
1308
|
+
focusNext();
|
|
1309
|
+
}
|
|
1310
|
+
if (input === shiftTab) {
|
|
1311
|
+
focusPrevious();
|
|
1312
|
+
}
|
|
1313
|
+
};
|
|
1314
|
+
internal_eventEmitter.on("input", handleTabNavigation);
|
|
1315
|
+
const emitter = internal_eventEmitter;
|
|
1316
|
+
return () => {
|
|
1317
|
+
emitter.off("input", handleTabNavigation);
|
|
1318
|
+
};
|
|
1319
|
+
}, [isFocusEnabled, focusNext, focusPrevious, internal_eventEmitter]);
|
|
1320
|
+
const enableFocus = useCallback(() => {
|
|
1321
|
+
setIsFocusEnabled(true);
|
|
1322
|
+
}, []);
|
|
1323
|
+
const disableFocus = useCallback(() => {
|
|
1324
|
+
setIsFocusEnabled(false);
|
|
1325
|
+
}, []);
|
|
1326
|
+
const focus = useCallback((id) => {
|
|
1327
|
+
setFocusables((currentFocusables) => {
|
|
1328
|
+
const hasFocusableId = currentFocusables.some((focusable) => focusable?.id === id);
|
|
1329
|
+
if (hasFocusableId) {
|
|
1330
|
+
setActiveFocusId(id);
|
|
1331
|
+
}
|
|
1332
|
+
return currentFocusables;
|
|
1333
|
+
});
|
|
1334
|
+
}, []);
|
|
1335
|
+
const addFocusable = useCallback((id, { autoFocus }) => {
|
|
1336
|
+
setFocusables((currentFocusables) => {
|
|
1337
|
+
focusablesCountRef.current = currentFocusables.length + 1;
|
|
1338
|
+
return [
|
|
1339
|
+
...currentFocusables,
|
|
1340
|
+
{
|
|
1341
|
+
id,
|
|
1342
|
+
isActive: true
|
|
1343
|
+
}
|
|
1344
|
+
];
|
|
1345
|
+
});
|
|
1346
|
+
if (autoFocus) {
|
|
1347
|
+
setActiveFocusId((currentActiveFocusId) => {
|
|
1348
|
+
if (!currentActiveFocusId) {
|
|
1349
|
+
return id;
|
|
1350
|
+
}
|
|
1351
|
+
return currentActiveFocusId;
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
}, []);
|
|
1355
|
+
const removeFocusable = useCallback((id) => {
|
|
1356
|
+
setActiveFocusId((currentActiveFocusId) => {
|
|
1357
|
+
if (currentActiveFocusId === id) {
|
|
1358
|
+
return void 0;
|
|
1359
|
+
}
|
|
1360
|
+
return currentActiveFocusId;
|
|
1361
|
+
});
|
|
1362
|
+
setFocusables((currentFocusables) => {
|
|
1363
|
+
const filtered = currentFocusables.filter((focusable) => focusable.id !== id);
|
|
1364
|
+
focusablesCountRef.current = filtered.length;
|
|
1365
|
+
return filtered;
|
|
1366
|
+
});
|
|
1367
|
+
}, []);
|
|
1368
|
+
const activateFocusable = useCallback((id) => {
|
|
1369
|
+
setFocusables(
|
|
1370
|
+
(currentFocusables) => currentFocusables.map((focusable) => {
|
|
1371
|
+
if (focusable.id !== id) {
|
|
1372
|
+
return focusable;
|
|
1373
|
+
}
|
|
1374
|
+
return {
|
|
1375
|
+
id,
|
|
1376
|
+
isActive: true
|
|
1377
|
+
};
|
|
1378
|
+
})
|
|
1379
|
+
);
|
|
1380
|
+
}, []);
|
|
1381
|
+
const deactivateFocusable = useCallback((id) => {
|
|
1382
|
+
setActiveFocusId((currentActiveFocusId) => {
|
|
1383
|
+
if (currentActiveFocusId === id) {
|
|
1384
|
+
return void 0;
|
|
1385
|
+
}
|
|
1386
|
+
return currentActiveFocusId;
|
|
1387
|
+
});
|
|
1388
|
+
setFocusables(
|
|
1389
|
+
(currentFocusables) => currentFocusables.map((focusable) => {
|
|
1390
|
+
if (focusable.id !== id) {
|
|
1391
|
+
return focusable;
|
|
1392
|
+
}
|
|
1393
|
+
return {
|
|
1394
|
+
id,
|
|
1395
|
+
isActive: false
|
|
1396
|
+
};
|
|
1397
|
+
})
|
|
1398
|
+
);
|
|
1399
|
+
}, []);
|
|
1400
|
+
useEffect(
|
|
1401
|
+
() => () => {
|
|
1402
|
+
const canWriteToStdout = !stdout.destroyed && !stdout.writableEnded;
|
|
1403
|
+
if (interactive && canWriteToStdout) {
|
|
1404
|
+
stdout.write(cursorShow);
|
|
1405
|
+
}
|
|
1406
|
+
if (isRawModeSupported && rawModeEnabledCount.current > 0) {
|
|
1407
|
+
disableRawMode();
|
|
1408
|
+
}
|
|
1409
|
+
if (bracketedPasteModeEnabledCount.current > 0) {
|
|
1410
|
+
if (stdout.isTTY && canWriteToStdout) {
|
|
1411
|
+
stdout.write("\x1B[?2004l");
|
|
1412
|
+
}
|
|
1413
|
+
bracketedPasteModeEnabledCount.current = 0;
|
|
1414
|
+
}
|
|
1415
|
+
},
|
|
1416
|
+
[stdout, isRawModeSupported, disableRawMode, interactive]
|
|
1417
|
+
);
|
|
1418
|
+
const appContextValue = useMemo(() => {
|
|
1419
|
+
return {
|
|
1420
|
+
exit: handleExit,
|
|
1421
|
+
waitUntilRenderFlush: onWaitUntilRenderFlush
|
|
1422
|
+
};
|
|
1423
|
+
}, [handleExit, onWaitUntilRenderFlush]);
|
|
1424
|
+
const stdinContextValue = useMemo(() => {
|
|
1425
|
+
return {
|
|
1426
|
+
internal_eventEmitter,
|
|
1427
|
+
internal_exitOnCtrlC: exitOnCtrlC,
|
|
1428
|
+
isRawModeSupported,
|
|
1429
|
+
setBracketedPasteMode: handleSetBracketedPasteMode,
|
|
1430
|
+
setRawMode: handleSetRawMode,
|
|
1431
|
+
stdin
|
|
1432
|
+
};
|
|
1433
|
+
}, [stdin, handleSetRawMode, handleSetBracketedPasteMode, isRawModeSupported, exitOnCtrlC, internal_eventEmitter]);
|
|
1434
|
+
const stdoutContextValue = useMemo(
|
|
1435
|
+
() => {
|
|
1436
|
+
return {
|
|
1437
|
+
stdout,
|
|
1438
|
+
write: writeToStdout
|
|
1439
|
+
};
|
|
1440
|
+
},
|
|
1441
|
+
[stdout, writeToStdout]
|
|
1442
|
+
);
|
|
1443
|
+
const stderrContextValue = useMemo(
|
|
1444
|
+
() => {
|
|
1445
|
+
return {
|
|
1446
|
+
stderr,
|
|
1447
|
+
write: writeToStderr
|
|
1448
|
+
};
|
|
1449
|
+
},
|
|
1450
|
+
[stderr, writeToStderr]
|
|
1451
|
+
);
|
|
1452
|
+
const cursorContextValue = useMemo(
|
|
1453
|
+
() => {
|
|
1454
|
+
return {
|
|
1455
|
+
setCursorPosition
|
|
1456
|
+
};
|
|
1457
|
+
},
|
|
1458
|
+
[setCursorPosition]
|
|
1459
|
+
);
|
|
1460
|
+
const focusContextValue = useMemo(() => {
|
|
1461
|
+
return {
|
|
1462
|
+
activate: activateFocusable,
|
|
1463
|
+
activeId: activeFocusId,
|
|
1464
|
+
add: addFocusable,
|
|
1465
|
+
deactivate: deactivateFocusable,
|
|
1466
|
+
disableFocus,
|
|
1467
|
+
enableFocus,
|
|
1468
|
+
focus,
|
|
1469
|
+
focusNext,
|
|
1470
|
+
focusPrevious,
|
|
1471
|
+
remove: removeFocusable
|
|
1472
|
+
};
|
|
1473
|
+
}, [activeFocusId, addFocusable, removeFocusable, activateFocusable, deactivateFocusable, enableFocus, disableFocus, focusNext, focusPrevious, focus]);
|
|
1474
|
+
const animationContextValue = useMemo(
|
|
1475
|
+
() => ({
|
|
1476
|
+
renderThrottleMs,
|
|
1477
|
+
subscribe: animationSubscribe
|
|
1478
|
+
}),
|
|
1479
|
+
[animationSubscribe, renderThrottleMs]
|
|
1480
|
+
);
|
|
1481
|
+
return jsx(AppContext.Provider, { value: appContextValue, children: jsx(StdinContext.Provider, { value: stdinContextValue, children: jsx(StdoutContext.Provider, { value: stdoutContextValue, children: jsx(StderrContext.Provider, { value: stderrContextValue, children: jsx(FocusContext.Provider, { value: focusContextValue, children: jsx(animationContext.Provider, { value: animationContextValue, children: jsx(CursorContext.Provider, { value: cursorContextValue, children: jsx(ErrorBoundary, { onError: handleExit, children }) }) }) }) }) }) }) });
|
|
1482
|
+
};
|
|
1483
|
+
App.displayName = "InternalApp";
|
|
1484
|
+
|
|
1485
|
+
const showCursorEscape = "\x1B[?25h";
|
|
1486
|
+
const hideCursorEscape = "\x1B[?25l";
|
|
1487
|
+
const cursorPositionChanged = (a, b) => a?.x !== b?.x || a?.y !== b?.y;
|
|
1488
|
+
const buildCursorSuffix = (visibleLineCount, cursorPosition) => {
|
|
1489
|
+
if (!cursorPosition) {
|
|
1490
|
+
return "";
|
|
1491
|
+
}
|
|
1492
|
+
const moveUp = visibleLineCount - cursorPosition.y;
|
|
1493
|
+
return (moveUp > 0 ? cursorUp(moveUp) : "") + cursorTo(cursorPosition.x) + showCursorEscape;
|
|
1494
|
+
};
|
|
1495
|
+
const buildReturnToBottom = (previousLineCount, previousCursorPosition) => {
|
|
1496
|
+
if (!previousCursorPosition) {
|
|
1497
|
+
return "";
|
|
1498
|
+
}
|
|
1499
|
+
const down = previousLineCount - 1 - previousCursorPosition.y;
|
|
1500
|
+
return (down > 0 ? cursorDown(down) : "") + cursorTo(0);
|
|
1501
|
+
};
|
|
1502
|
+
const buildCursorOnlySequence = (input) => {
|
|
1503
|
+
const hidePrefix = input.cursorWasShown ? hideCursorEscape : "";
|
|
1504
|
+
const returnToBottom = buildReturnToBottom(input.previousLineCount, input.previousCursorPosition);
|
|
1505
|
+
const cursorSuffix = buildCursorSuffix(input.visibleLineCount, input.cursorPosition);
|
|
1506
|
+
return hidePrefix + returnToBottom + cursorSuffix;
|
|
1507
|
+
};
|
|
1508
|
+
const buildReturnToBottomPrefix = (cursorWasShown, previousLineCount, previousCursorPosition) => {
|
|
1509
|
+
if (!cursorWasShown) {
|
|
1510
|
+
return "";
|
|
1511
|
+
}
|
|
1512
|
+
return hideCursorEscape + buildReturnToBottom(previousLineCount, previousCursorPosition);
|
|
1513
|
+
};
|
|
1514
|
+
|
|
1515
|
+
const instances = /* @__PURE__ */ new WeakMap();
|
|
1516
|
+
|
|
1517
|
+
const visibleLineCount = (lines, string_) => string_.endsWith("\n") ? lines.length - 1 : lines.length;
|
|
1518
|
+
const getViewportRows = (stream) => stream.rows || Infinity;
|
|
1519
|
+
const clampToViewport = (lineCount, stream) => Math.min(lineCount, getViewportRows(stream));
|
|
1520
|
+
const createStandard = (stream, { showCursor = false } = {}) => {
|
|
1521
|
+
let previousLineCount = 0;
|
|
1522
|
+
let previousOutput = "";
|
|
1523
|
+
let hasHiddenCursor = false;
|
|
1524
|
+
let cursorPosition;
|
|
1525
|
+
let cursorDirty = false;
|
|
1526
|
+
let previousCursorPosition;
|
|
1527
|
+
let cursorWasShown = false;
|
|
1528
|
+
const getActiveCursor = () => cursorDirty ? cursorPosition : void 0;
|
|
1529
|
+
const hasChanges = (string_, activeCursor) => {
|
|
1530
|
+
const cursorChanged = cursorPositionChanged(activeCursor, previousCursorPosition);
|
|
1531
|
+
return string_ !== previousOutput || cursorChanged;
|
|
1532
|
+
};
|
|
1533
|
+
const render = (string_) => {
|
|
1534
|
+
if (!showCursor && !hasHiddenCursor) {
|
|
1535
|
+
stream.write(cursorHide);
|
|
1536
|
+
hasHiddenCursor = true;
|
|
1537
|
+
}
|
|
1538
|
+
const activeCursor = getActiveCursor();
|
|
1539
|
+
cursorDirty = false;
|
|
1540
|
+
const cursorChanged = cursorPositionChanged(activeCursor, previousCursorPosition);
|
|
1541
|
+
if (!hasChanges(string_, activeCursor)) {
|
|
1542
|
+
return false;
|
|
1543
|
+
}
|
|
1544
|
+
const lines = string_.split("\n");
|
|
1545
|
+
const visibleCount = visibleLineCount(lines, string_);
|
|
1546
|
+
const cursorSuffix = buildCursorSuffix(visibleCount, activeCursor);
|
|
1547
|
+
if (string_ === previousOutput && cursorChanged) {
|
|
1548
|
+
stream.write(
|
|
1549
|
+
buildCursorOnlySequence({
|
|
1550
|
+
cursorPosition: activeCursor,
|
|
1551
|
+
cursorWasShown,
|
|
1552
|
+
previousCursorPosition,
|
|
1553
|
+
previousLineCount,
|
|
1554
|
+
visibleLineCount: visibleCount
|
|
1555
|
+
})
|
|
1556
|
+
);
|
|
1557
|
+
} else {
|
|
1558
|
+
previousOutput = string_;
|
|
1559
|
+
const returnPrefix = buildReturnToBottomPrefix(cursorWasShown, previousLineCount, previousCursorPosition);
|
|
1560
|
+
stream.write(returnPrefix + eraseLines(clampToViewport(previousLineCount, stream)) + string_ + cursorSuffix);
|
|
1561
|
+
previousLineCount = lines.length;
|
|
1562
|
+
}
|
|
1563
|
+
previousCursorPosition = activeCursor ? { ...activeCursor } : void 0;
|
|
1564
|
+
cursorWasShown = activeCursor !== void 0;
|
|
1565
|
+
return true;
|
|
1566
|
+
};
|
|
1567
|
+
render.clear = () => {
|
|
1568
|
+
const prefix = buildReturnToBottomPrefix(cursorWasShown, previousLineCount, previousCursorPosition);
|
|
1569
|
+
stream.write(prefix + eraseLines(clampToViewport(previousLineCount, stream)));
|
|
1570
|
+
previousOutput = "";
|
|
1571
|
+
previousLineCount = 0;
|
|
1572
|
+
previousCursorPosition = void 0;
|
|
1573
|
+
cursorWasShown = false;
|
|
1574
|
+
};
|
|
1575
|
+
render.done = () => {
|
|
1576
|
+
previousOutput = "";
|
|
1577
|
+
previousLineCount = 0;
|
|
1578
|
+
previousCursorPosition = void 0;
|
|
1579
|
+
cursorWasShown = false;
|
|
1580
|
+
if (!showCursor) {
|
|
1581
|
+
stream.write(cursorShow);
|
|
1582
|
+
hasHiddenCursor = false;
|
|
1583
|
+
}
|
|
1584
|
+
};
|
|
1585
|
+
render.reset = () => {
|
|
1586
|
+
previousOutput = "";
|
|
1587
|
+
previousLineCount = 0;
|
|
1588
|
+
previousCursorPosition = void 0;
|
|
1589
|
+
cursorWasShown = false;
|
|
1590
|
+
};
|
|
1591
|
+
render.sync = (string_) => {
|
|
1592
|
+
const activeCursor = cursorDirty ? cursorPosition : void 0;
|
|
1593
|
+
cursorDirty = false;
|
|
1594
|
+
const lines = string_.split("\n");
|
|
1595
|
+
previousOutput = string_;
|
|
1596
|
+
previousLineCount = lines.length;
|
|
1597
|
+
if (!activeCursor && cursorWasShown) {
|
|
1598
|
+
stream.write(hideCursorEscape);
|
|
1599
|
+
}
|
|
1600
|
+
if (activeCursor) {
|
|
1601
|
+
stream.write(buildCursorSuffix(visibleLineCount(lines, string_), activeCursor));
|
|
1602
|
+
}
|
|
1603
|
+
previousCursorPosition = activeCursor ? { ...activeCursor } : void 0;
|
|
1604
|
+
cursorWasShown = activeCursor !== void 0;
|
|
1605
|
+
};
|
|
1606
|
+
render.setCursorPosition = (position) => {
|
|
1607
|
+
cursorPosition = position;
|
|
1608
|
+
cursorDirty = true;
|
|
1609
|
+
};
|
|
1610
|
+
render.isCursorDirty = () => cursorDirty;
|
|
1611
|
+
render.willRender = (string_) => hasChanges(string_, getActiveCursor());
|
|
1612
|
+
return render;
|
|
1613
|
+
};
|
|
1614
|
+
const createIncremental = (stream, { showCursor = false } = {}) => {
|
|
1615
|
+
let previousLines = [];
|
|
1616
|
+
let previousOutput = "";
|
|
1617
|
+
let hasHiddenCursor = false;
|
|
1618
|
+
let cursorPosition;
|
|
1619
|
+
let cursorDirty = false;
|
|
1620
|
+
let previousCursorPosition;
|
|
1621
|
+
let cursorWasShown = false;
|
|
1622
|
+
const getActiveCursor = () => cursorDirty ? cursorPosition : void 0;
|
|
1623
|
+
const hasChanges = (string_, activeCursor) => {
|
|
1624
|
+
const cursorChanged = cursorPositionChanged(activeCursor, previousCursorPosition);
|
|
1625
|
+
return string_ !== previousOutput || cursorChanged;
|
|
1626
|
+
};
|
|
1627
|
+
const render = (string_) => {
|
|
1628
|
+
if (!showCursor && !hasHiddenCursor) {
|
|
1629
|
+
stream.write(cursorHide);
|
|
1630
|
+
hasHiddenCursor = true;
|
|
1631
|
+
}
|
|
1632
|
+
const activeCursor = getActiveCursor();
|
|
1633
|
+
cursorDirty = false;
|
|
1634
|
+
const cursorChanged = cursorPositionChanged(activeCursor, previousCursorPosition);
|
|
1635
|
+
if (!hasChanges(string_, activeCursor)) {
|
|
1636
|
+
return false;
|
|
1637
|
+
}
|
|
1638
|
+
const nextLines = string_.split("\n");
|
|
1639
|
+
const visibleCount = visibleLineCount(nextLines, string_);
|
|
1640
|
+
const previousVisible = visibleLineCount(previousLines, previousOutput);
|
|
1641
|
+
if (string_ === previousOutput && cursorChanged) {
|
|
1642
|
+
stream.write(
|
|
1643
|
+
buildCursorOnlySequence({
|
|
1644
|
+
cursorPosition: activeCursor,
|
|
1645
|
+
cursorWasShown,
|
|
1646
|
+
previousCursorPosition,
|
|
1647
|
+
previousLineCount: previousLines.length,
|
|
1648
|
+
visibleLineCount: visibleCount
|
|
1649
|
+
})
|
|
1650
|
+
);
|
|
1651
|
+
previousCursorPosition = activeCursor ? { ...activeCursor } : void 0;
|
|
1652
|
+
cursorWasShown = activeCursor !== void 0;
|
|
1653
|
+
return true;
|
|
1654
|
+
}
|
|
1655
|
+
const returnPrefix = buildReturnToBottomPrefix(cursorWasShown, previousLines.length, previousCursorPosition);
|
|
1656
|
+
if (string_ === "\n" || previousOutput.length === 0) {
|
|
1657
|
+
const cursorSuffix2 = buildCursorSuffix(visibleCount, activeCursor);
|
|
1658
|
+
stream.write(returnPrefix + eraseLines(clampToViewport(previousLines.length, stream)) + string_ + cursorSuffix2);
|
|
1659
|
+
cursorWasShown = activeCursor !== void 0;
|
|
1660
|
+
previousCursorPosition = activeCursor ? { ...activeCursor } : void 0;
|
|
1661
|
+
previousOutput = string_;
|
|
1662
|
+
previousLines = nextLines;
|
|
1663
|
+
return true;
|
|
1664
|
+
}
|
|
1665
|
+
const hasTrailingNewline = string_.endsWith("\n");
|
|
1666
|
+
const buffer = [returnPrefix];
|
|
1667
|
+
const viewportRows = getViewportRows(stream);
|
|
1668
|
+
if (visibleCount < previousVisible) {
|
|
1669
|
+
const previousHadTrailingNewline = previousOutput.endsWith("\n");
|
|
1670
|
+
const extraSlot = previousHadTrailingNewline ? 1 : 0;
|
|
1671
|
+
buffer.push(eraseLines(Math.min(previousVisible - visibleCount + extraSlot, viewportRows)), cursorUp(Math.min(visibleCount, viewportRows - 1)));
|
|
1672
|
+
} else {
|
|
1673
|
+
buffer.push(cursorUp(Math.min(previousVisible - 1, viewportRows - 1)));
|
|
1674
|
+
}
|
|
1675
|
+
for (let i = 0; i < visibleCount; i++) {
|
|
1676
|
+
const isLastLine = i === visibleCount - 1;
|
|
1677
|
+
if (nextLines[i] === previousLines[i]) {
|
|
1678
|
+
if (!isLastLine || hasTrailingNewline) {
|
|
1679
|
+
buffer.push(cursorNextLine());
|
|
1680
|
+
}
|
|
1681
|
+
continue;
|
|
1682
|
+
}
|
|
1683
|
+
buffer.push(
|
|
1684
|
+
cursorTo(0) + nextLines[i] + eraseLineEnd + (isLastLine && !hasTrailingNewline ? "" : "\n")
|
|
1685
|
+
);
|
|
1686
|
+
}
|
|
1687
|
+
const cursorSuffix = buildCursorSuffix(visibleCount, activeCursor);
|
|
1688
|
+
buffer.push(cursorSuffix);
|
|
1689
|
+
stream.write(buffer.join(""));
|
|
1690
|
+
cursorWasShown = activeCursor !== void 0;
|
|
1691
|
+
previousCursorPosition = activeCursor ? { ...activeCursor } : void 0;
|
|
1692
|
+
previousOutput = string_;
|
|
1693
|
+
previousLines = nextLines;
|
|
1694
|
+
return true;
|
|
1695
|
+
};
|
|
1696
|
+
render.clear = () => {
|
|
1697
|
+
const prefix = buildReturnToBottomPrefix(cursorWasShown, previousLines.length, previousCursorPosition);
|
|
1698
|
+
stream.write(prefix + eraseLines(clampToViewport(previousLines.length, stream)));
|
|
1699
|
+
previousOutput = "";
|
|
1700
|
+
previousLines = [];
|
|
1701
|
+
previousCursorPosition = void 0;
|
|
1702
|
+
cursorWasShown = false;
|
|
1703
|
+
};
|
|
1704
|
+
render.done = () => {
|
|
1705
|
+
previousOutput = "";
|
|
1706
|
+
previousLines = [];
|
|
1707
|
+
previousCursorPosition = void 0;
|
|
1708
|
+
cursorWasShown = false;
|
|
1709
|
+
if (!showCursor) {
|
|
1710
|
+
stream.write(cursorShow);
|
|
1711
|
+
hasHiddenCursor = false;
|
|
1712
|
+
}
|
|
1713
|
+
};
|
|
1714
|
+
render.reset = () => {
|
|
1715
|
+
previousOutput = "";
|
|
1716
|
+
previousLines = [];
|
|
1717
|
+
previousCursorPosition = void 0;
|
|
1718
|
+
cursorWasShown = false;
|
|
1719
|
+
};
|
|
1720
|
+
render.sync = (string_) => {
|
|
1721
|
+
const activeCursor = cursorDirty ? cursorPosition : void 0;
|
|
1722
|
+
cursorDirty = false;
|
|
1723
|
+
const lines = string_.split("\n");
|
|
1724
|
+
previousOutput = string_;
|
|
1725
|
+
previousLines = lines;
|
|
1726
|
+
if (!activeCursor && cursorWasShown) {
|
|
1727
|
+
stream.write(hideCursorEscape);
|
|
1728
|
+
}
|
|
1729
|
+
if (activeCursor) {
|
|
1730
|
+
stream.write(buildCursorSuffix(visibleLineCount(lines, string_), activeCursor));
|
|
1731
|
+
}
|
|
1732
|
+
previousCursorPosition = activeCursor ? { ...activeCursor } : void 0;
|
|
1733
|
+
cursorWasShown = activeCursor !== void 0;
|
|
1734
|
+
};
|
|
1735
|
+
render.setCursorPosition = (position) => {
|
|
1736
|
+
cursorPosition = position;
|
|
1737
|
+
cursorDirty = true;
|
|
1738
|
+
};
|
|
1739
|
+
render.isCursorDirty = () => cursorDirty;
|
|
1740
|
+
render.willRender = (string_) => hasChanges(string_, getActiveCursor());
|
|
1741
|
+
return render;
|
|
1742
|
+
};
|
|
1743
|
+
const create = (stream, { incremental = false, showCursor = false } = {}) => {
|
|
1744
|
+
if (incremental) {
|
|
1745
|
+
return createIncremental(stream, { showCursor });
|
|
1746
|
+
}
|
|
1747
|
+
return createStandard(stream, { showCursor });
|
|
1748
|
+
};
|
|
1749
|
+
const logUpdate = { create };
|
|
1750
|
+
|
|
1751
|
+
let cachedRendererClass;
|
|
1752
|
+
const getRendererClass = () => {
|
|
1753
|
+
if (cachedRendererClass === false) {
|
|
1754
|
+
return void 0;
|
|
1755
|
+
}
|
|
1756
|
+
if (cachedRendererClass !== void 0) {
|
|
1757
|
+
return cachedRendererClass;
|
|
1758
|
+
}
|
|
1759
|
+
try {
|
|
1760
|
+
const binding = require("../../index.js");
|
|
1761
|
+
cachedRendererClass = binding.Renderer;
|
|
1762
|
+
return cachedRendererClass;
|
|
1763
|
+
} catch {
|
|
1764
|
+
cachedRendererClass = false;
|
|
1765
|
+
return void 0;
|
|
1766
|
+
}
|
|
1767
|
+
};
|
|
1768
|
+
const createNative = (stream) => {
|
|
1769
|
+
const RendererClass = getRendererClass();
|
|
1770
|
+
if (!RendererClass) {
|
|
1771
|
+
return void 0;
|
|
1772
|
+
}
|
|
1773
|
+
let renderer;
|
|
1774
|
+
let currentWidth = 0;
|
|
1775
|
+
let currentHeight = 0;
|
|
1776
|
+
const ensureRenderer = (width, height) => {
|
|
1777
|
+
if (!renderer || currentWidth !== width || currentHeight !== height) {
|
|
1778
|
+
if (renderer) {
|
|
1779
|
+
renderer.resize(width, height);
|
|
1780
|
+
} else {
|
|
1781
|
+
renderer = new RendererClass(width, height);
|
|
1782
|
+
}
|
|
1783
|
+
currentWidth = width;
|
|
1784
|
+
currentHeight = height;
|
|
1785
|
+
}
|
|
1786
|
+
};
|
|
1787
|
+
return {
|
|
1788
|
+
clear() {
|
|
1789
|
+
if (renderer) {
|
|
1790
|
+
const blank = new Uint32Array(currentWidth * currentHeight * 2);
|
|
1791
|
+
const defaultAttribute = 0 << 16 | 255 << 8 | 255;
|
|
1792
|
+
for (let index = 0; index < blank.length; index += 2) {
|
|
1793
|
+
blank[index] = 32;
|
|
1794
|
+
blank[index + 1] = defaultAttribute;
|
|
1795
|
+
}
|
|
1796
|
+
renderer.render(blank);
|
|
1797
|
+
}
|
|
1798
|
+
},
|
|
1799
|
+
destroy() {
|
|
1800
|
+
renderer = void 0;
|
|
1801
|
+
},
|
|
1802
|
+
render(buffer, width, height) {
|
|
1803
|
+
ensureRenderer(width, height);
|
|
1804
|
+
if (!renderer) {
|
|
1805
|
+
return;
|
|
1806
|
+
}
|
|
1807
|
+
if (stream.isTTY) {
|
|
1808
|
+
renderer.writeRaw("\x1B[?2026h");
|
|
1809
|
+
}
|
|
1810
|
+
try {
|
|
1811
|
+
renderer.render(buffer);
|
|
1812
|
+
} finally {
|
|
1813
|
+
if (stream.isTTY) {
|
|
1814
|
+
renderer.writeRaw("\x1B[?2026l");
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
},
|
|
1818
|
+
resize(width, height) {
|
|
1819
|
+
ensureRenderer(width, height);
|
|
1820
|
+
}
|
|
1821
|
+
};
|
|
1822
|
+
};
|
|
1823
|
+
|
|
1824
|
+
const bsu = "\x1B[?2026h";
|
|
1825
|
+
const esu = "\x1B[?2026l";
|
|
1826
|
+
function shouldSynchronize(stream, interactive) {
|
|
1827
|
+
return "isTTY" in stream && stream.isTTY && (interactive ?? !isInCi);
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
if (!console.Console) {
|
|
1831
|
+
console.Console = Console;
|
|
1832
|
+
}
|
|
1833
|
+
const noop = () => {
|
|
1834
|
+
};
|
|
1835
|
+
const yieldImmediate = async () => new Promise((resolve) => {
|
|
1836
|
+
setImmediate(resolve);
|
|
1837
|
+
});
|
|
1838
|
+
const kittyQueryEscapeByte = 27;
|
|
1839
|
+
const kittyQueryOpenBracketByte = 91;
|
|
1840
|
+
const kittyQueryQuestionMarkByte = 63;
|
|
1841
|
+
const kittyQueryLetterByte = 117;
|
|
1842
|
+
const zeroByte = 48;
|
|
1843
|
+
const nineByte = 57;
|
|
1844
|
+
const isDigitByte = (byte) => byte >= zeroByte && byte <= nineByte;
|
|
1845
|
+
const matchKittyQueryResponse = (buffer, startIndex) => {
|
|
1846
|
+
if (buffer[startIndex] !== kittyQueryEscapeByte || buffer[startIndex + 1] !== kittyQueryOpenBracketByte || buffer[startIndex + 2] !== kittyQueryQuestionMarkByte) {
|
|
1847
|
+
return void 0;
|
|
1848
|
+
}
|
|
1849
|
+
let index = startIndex + 3;
|
|
1850
|
+
const digitsStartIndex = index;
|
|
1851
|
+
while (index < buffer.length && isDigitByte(buffer[index])) {
|
|
1852
|
+
index++;
|
|
1853
|
+
}
|
|
1854
|
+
if (index === digitsStartIndex) {
|
|
1855
|
+
return void 0;
|
|
1856
|
+
}
|
|
1857
|
+
if (index === buffer.length) {
|
|
1858
|
+
return { state: "partial" };
|
|
1859
|
+
}
|
|
1860
|
+
if (buffer[index] === kittyQueryLetterByte) {
|
|
1861
|
+
return { endIndex: index, state: "complete" };
|
|
1862
|
+
}
|
|
1863
|
+
return void 0;
|
|
1864
|
+
};
|
|
1865
|
+
const hasCompleteKittyQueryResponse = (buffer) => {
|
|
1866
|
+
for (let index = 0; index < buffer.length; index++) {
|
|
1867
|
+
const match = matchKittyQueryResponse(buffer, index);
|
|
1868
|
+
if (match?.state === "complete") {
|
|
1869
|
+
return true;
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
return false;
|
|
1873
|
+
};
|
|
1874
|
+
const stripKittyQueryResponsesAndTrailingPartial = (buffer) => {
|
|
1875
|
+
const keptBytes = [];
|
|
1876
|
+
let index = 0;
|
|
1877
|
+
while (index < buffer.length) {
|
|
1878
|
+
const match = matchKittyQueryResponse(buffer, index);
|
|
1879
|
+
if (match?.state === "complete") {
|
|
1880
|
+
index = match.endIndex + 1;
|
|
1881
|
+
continue;
|
|
1882
|
+
}
|
|
1883
|
+
if (match?.state === "partial") {
|
|
1884
|
+
break;
|
|
1885
|
+
}
|
|
1886
|
+
keptBytes.push(buffer[index]);
|
|
1887
|
+
index++;
|
|
1888
|
+
}
|
|
1889
|
+
return keptBytes;
|
|
1890
|
+
};
|
|
1891
|
+
const shouldClearTerminalForFrame = ({
|
|
1892
|
+
isTty,
|
|
1893
|
+
isUnmounting,
|
|
1894
|
+
nextOutputHeight,
|
|
1895
|
+
previousOutputHeight,
|
|
1896
|
+
viewportRows
|
|
1897
|
+
}) => {
|
|
1898
|
+
if (!isTty) {
|
|
1899
|
+
return false;
|
|
1900
|
+
}
|
|
1901
|
+
const hadPreviousFrame = previousOutputHeight > 0;
|
|
1902
|
+
const wasFullscreen = previousOutputHeight >= viewportRows;
|
|
1903
|
+
const wasOverflowing = previousOutputHeight > viewportRows;
|
|
1904
|
+
const isOverflowing = nextOutputHeight > viewportRows;
|
|
1905
|
+
const isLeavingFullscreen = wasFullscreen && nextOutputHeight < viewportRows;
|
|
1906
|
+
const shouldClearOnUnmount = isUnmounting && wasFullscreen;
|
|
1907
|
+
return (
|
|
1908
|
+
// Overflowing frames still need full clear fallback.
|
|
1909
|
+
wasOverflowing || isOverflowing && hadPreviousFrame || isLeavingFullscreen || shouldClearOnUnmount
|
|
1910
|
+
);
|
|
1911
|
+
};
|
|
1912
|
+
const isErrorInput = (value) => value instanceof Error || Object.prototype.toString.call(value) === "[object Error]";
|
|
1913
|
+
const getWritableStreamState = (stdout) => {
|
|
1914
|
+
const canWriteToStdout = !stdout.destroyed && !stdout.writableEnded && (stdout.writable ?? true);
|
|
1915
|
+
const hasWritableState = stdout._writableState !== void 0 || stdout.writableLength !== void 0;
|
|
1916
|
+
return {
|
|
1917
|
+
canWriteToStdout,
|
|
1918
|
+
hasWritableState
|
|
1919
|
+
};
|
|
1920
|
+
};
|
|
1921
|
+
const settleThrottle = (throttled, canWriteToStdout) => {
|
|
1922
|
+
if (!throttled || typeof throttled.flush !== "function") {
|
|
1923
|
+
return;
|
|
1924
|
+
}
|
|
1925
|
+
const throttledValue = throttled;
|
|
1926
|
+
if (canWriteToStdout) {
|
|
1927
|
+
throttledValue.flush();
|
|
1928
|
+
} else if (typeof throttledValue.cancel === "function") {
|
|
1929
|
+
throttledValue.cancel();
|
|
1930
|
+
}
|
|
1931
|
+
};
|
|
1932
|
+
class Ink {
|
|
1933
|
+
/**
|
|
1934
|
+
* Whether this instance is using concurrent rendering mode.
|
|
1935
|
+
*/
|
|
1936
|
+
isConcurrent;
|
|
1937
|
+
options;
|
|
1938
|
+
log;
|
|
1939
|
+
manualCursorPosition;
|
|
1940
|
+
renderedCursorPosition;
|
|
1941
|
+
renderedCursorRequested;
|
|
1942
|
+
throttledLog;
|
|
1943
|
+
isScreenReaderEnabled;
|
|
1944
|
+
interactive;
|
|
1945
|
+
renderThrottleMs;
|
|
1946
|
+
alternateScreen;
|
|
1947
|
+
// Ignore last render after unmounting a tree to prevent empty output before exit
|
|
1948
|
+
isUnmounted;
|
|
1949
|
+
isUnmounting;
|
|
1950
|
+
lastOutput;
|
|
1951
|
+
lastOutputToRender;
|
|
1952
|
+
lastOutputHeight;
|
|
1953
|
+
lastTerminalWidth;
|
|
1954
|
+
nativeLog;
|
|
1955
|
+
useNativeRenderer;
|
|
1956
|
+
container;
|
|
1957
|
+
rootNode;
|
|
1958
|
+
// This variable is used only in debug mode to store full static output
|
|
1959
|
+
// so that it's rerendered every time, not just new static parts, like in non-debug mode
|
|
1960
|
+
fullStaticOutput;
|
|
1961
|
+
exitPromise;
|
|
1962
|
+
exitResult;
|
|
1963
|
+
beforeExitHandler;
|
|
1964
|
+
restoreConsole;
|
|
1965
|
+
unsubscribeResize;
|
|
1966
|
+
throttledOnRender;
|
|
1967
|
+
hasPendingThrottledRender = false;
|
|
1968
|
+
kittyProtocolEnabled = false;
|
|
1969
|
+
cancelKittyDetection;
|
|
1970
|
+
nextRenderCommit;
|
|
1971
|
+
deferredInitDone = false;
|
|
1972
|
+
constructor(options) {
|
|
1973
|
+
this.options = options;
|
|
1974
|
+
this.rootNode = createNode("ink-root");
|
|
1975
|
+
this.rootNode.onComputeLayout = this.calculateLayout;
|
|
1976
|
+
this.isScreenReaderEnabled = options.isScreenReaderEnabled ?? process$2.env["INK_SCREEN_READER"] === "true";
|
|
1977
|
+
this.interactive = this.resolveInteractiveOption(options.interactive);
|
|
1978
|
+
this.alternateScreen = false;
|
|
1979
|
+
const unthrottled = options.debug || this.isScreenReaderEnabled;
|
|
1980
|
+
const maxFps = options.maxFps ?? 30;
|
|
1981
|
+
const renderThrottleMs = maxFps > 0 ? Math.max(1, Math.ceil(1e3 / maxFps)) : 0;
|
|
1982
|
+
this.renderThrottleMs = unthrottled ? 0 : renderThrottleMs;
|
|
1983
|
+
const baseOnRender = unthrottled ? this.onRender : (() => {
|
|
1984
|
+
const throttled = throttle(this.onRender, renderThrottleMs, {
|
|
1985
|
+
leading: true,
|
|
1986
|
+
trailing: true
|
|
1987
|
+
});
|
|
1988
|
+
this.throttledOnRender = throttled;
|
|
1989
|
+
return () => {
|
|
1990
|
+
this.hasPendingThrottledRender = true;
|
|
1991
|
+
throttled();
|
|
1992
|
+
};
|
|
1993
|
+
})();
|
|
1994
|
+
if (unthrottled) {
|
|
1995
|
+
this.throttledOnRender = void 0;
|
|
1996
|
+
}
|
|
1997
|
+
if (options.standardReactLayoutTiming) {
|
|
1998
|
+
let isRenderScheduled = false;
|
|
1999
|
+
const deferredRender = () => {
|
|
2000
|
+
if (isRenderScheduled) {
|
|
2001
|
+
return;
|
|
2002
|
+
}
|
|
2003
|
+
isRenderScheduled = true;
|
|
2004
|
+
queueMicrotask(() => {
|
|
2005
|
+
isRenderScheduled = false;
|
|
2006
|
+
this.onRender();
|
|
2007
|
+
});
|
|
2008
|
+
};
|
|
2009
|
+
this.rootNode.onRender = deferredRender;
|
|
2010
|
+
this.rootNode.onImmediateRender = deferredRender;
|
|
2011
|
+
} else {
|
|
2012
|
+
this.rootNode.onRender = baseOnRender;
|
|
2013
|
+
this.rootNode.onImmediateRender = this.onRender;
|
|
2014
|
+
}
|
|
2015
|
+
this.log = logUpdate.create(options.stdout, {
|
|
2016
|
+
incremental: options.incrementalRendering
|
|
2017
|
+
});
|
|
2018
|
+
this.useNativeRenderer = options.useNativeRenderer ?? false;
|
|
2019
|
+
if (this.useNativeRenderer) {
|
|
2020
|
+
this.nativeLog = createNative(options.stdout);
|
|
2021
|
+
if (!this.nativeLog) {
|
|
2022
|
+
this.useNativeRenderer = false;
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
this.manualCursorPosition = void 0;
|
|
2026
|
+
this.renderedCursorPosition = void 0;
|
|
2027
|
+
this.renderedCursorRequested = false;
|
|
2028
|
+
this.throttledLog = unthrottled ? this.log : throttle(
|
|
2029
|
+
(output) => {
|
|
2030
|
+
const shouldWrite = this.log.willRender(output);
|
|
2031
|
+
const sync = this.shouldSync();
|
|
2032
|
+
if (sync && shouldWrite) {
|
|
2033
|
+
this.options.stdout.write(bsu);
|
|
2034
|
+
}
|
|
2035
|
+
this.log(output);
|
|
2036
|
+
if (sync && shouldWrite) {
|
|
2037
|
+
this.options.stdout.write(esu);
|
|
2038
|
+
}
|
|
2039
|
+
},
|
|
2040
|
+
void 0,
|
|
2041
|
+
{
|
|
2042
|
+
leading: true,
|
|
2043
|
+
trailing: true
|
|
2044
|
+
}
|
|
2045
|
+
);
|
|
2046
|
+
this.isUnmounted = false;
|
|
2047
|
+
this.isUnmounting = false;
|
|
2048
|
+
this.isConcurrent = options.concurrent ?? false;
|
|
2049
|
+
this.lastOutput = "";
|
|
2050
|
+
this.lastOutputToRender = "";
|
|
2051
|
+
this.lastOutputHeight = 0;
|
|
2052
|
+
this.lastTerminalWidth = getWindowSize(this.options.stdout).columns;
|
|
2053
|
+
this.fullStaticOutput = "";
|
|
2054
|
+
const rootTag = options.concurrent ? ConcurrentRoot : LegacyRoot;
|
|
2055
|
+
this.container = reconcilerInstance.createContainer(
|
|
2056
|
+
this.rootNode,
|
|
2057
|
+
rootTag,
|
|
2058
|
+
null,
|
|
2059
|
+
false,
|
|
2060
|
+
null,
|
|
2061
|
+
"id",
|
|
2062
|
+
() => {
|
|
2063
|
+
},
|
|
2064
|
+
() => {
|
|
2065
|
+
},
|
|
2066
|
+
() => {
|
|
2067
|
+
},
|
|
2068
|
+
() => {
|
|
2069
|
+
}
|
|
2070
|
+
);
|
|
2071
|
+
this.unsubscribeExit = onExit(this.unmount, { alwaysLast: false });
|
|
2072
|
+
this.setAlternateScreen(Boolean(options.alternateScreen));
|
|
2073
|
+
if (options.patchConsole) {
|
|
2074
|
+
this.patchConsole();
|
|
2075
|
+
}
|
|
2076
|
+
if (this.interactive) {
|
|
2077
|
+
options.stdout.on("resize", this.resized);
|
|
2078
|
+
this.unsubscribeResize = () => {
|
|
2079
|
+
options.stdout.off("resize", this.resized);
|
|
2080
|
+
};
|
|
2081
|
+
}
|
|
2082
|
+
this.initImmediateKittyKeyboard();
|
|
2083
|
+
if (process$2.env["DEV"] === "true") {
|
|
2084
|
+
reconcilerInstance.injectIntoDevTools();
|
|
2085
|
+
}
|
|
2086
|
+
this.exitPromise = new Promise((resolve, reject) => {
|
|
2087
|
+
this.resolveExitPromise = resolve;
|
|
2088
|
+
this.rejectExitPromise = reject;
|
|
2089
|
+
});
|
|
2090
|
+
void this.exitPromise.catch(noop);
|
|
2091
|
+
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Perform deferred initialization on the first render frame.
|
|
2094
|
+
* Kitty keyboard auto-detection is deferred here because the CSI ? u
|
|
2095
|
+
* query sets up a synchronous stdin listener with a 200ms timeout.
|
|
2096
|
+
* "enabled" mode runs immediately in the constructor (it's just a write).
|
|
2097
|
+
*/
|
|
2098
|
+
runDeferredInit() {
|
|
2099
|
+
if (this.deferredInitDone) {
|
|
2100
|
+
return;
|
|
2101
|
+
}
|
|
2102
|
+
this.deferredInitDone = true;
|
|
2103
|
+
this.initDeferredKittyKeyboard();
|
|
2104
|
+
}
|
|
2105
|
+
resized = () => {
|
|
2106
|
+
const currentWidth = getWindowSize(this.options.stdout).columns;
|
|
2107
|
+
if (currentWidth < this.lastTerminalWidth) {
|
|
2108
|
+
this.log.clear();
|
|
2109
|
+
this.lastOutput = "";
|
|
2110
|
+
this.lastOutputToRender = "";
|
|
2111
|
+
}
|
|
2112
|
+
clearStyledLineCache();
|
|
2113
|
+
this.calculateLayout();
|
|
2114
|
+
this.onRender();
|
|
2115
|
+
this.lastTerminalWidth = currentWidth;
|
|
2116
|
+
};
|
|
2117
|
+
resolveExitPromise = () => {
|
|
2118
|
+
};
|
|
2119
|
+
rejectExitPromise = () => {
|
|
2120
|
+
};
|
|
2121
|
+
unsubscribeExit = () => {
|
|
2122
|
+
};
|
|
2123
|
+
handleAppExit = (errorOrResult) => {
|
|
2124
|
+
if (this.isUnmounted || this.isUnmounting) {
|
|
2125
|
+
return;
|
|
2126
|
+
}
|
|
2127
|
+
if (isErrorInput(errorOrResult)) {
|
|
2128
|
+
this.unmount(errorOrResult);
|
|
2129
|
+
return;
|
|
2130
|
+
}
|
|
2131
|
+
this.exitResult = errorOrResult;
|
|
2132
|
+
this.unmount();
|
|
2133
|
+
};
|
|
2134
|
+
getActiveCursorPosition = () => {
|
|
2135
|
+
if (this.renderedCursorRequested) {
|
|
2136
|
+
return this.renderedCursorPosition;
|
|
2137
|
+
}
|
|
2138
|
+
return this.manualCursorPosition;
|
|
2139
|
+
};
|
|
2140
|
+
setCursorPosition = (position) => {
|
|
2141
|
+
this.manualCursorPosition = position;
|
|
2142
|
+
this.log.setCursorPosition(this.getActiveCursorPosition());
|
|
2143
|
+
};
|
|
2144
|
+
restoreLastOutput = () => {
|
|
2145
|
+
if (!this.interactive) {
|
|
2146
|
+
return;
|
|
2147
|
+
}
|
|
2148
|
+
this.log.setCursorPosition(this.getActiveCursorPosition());
|
|
2149
|
+
this.log(this.lastOutputToRender || `${this.lastOutput}
|
|
2150
|
+
`);
|
|
2151
|
+
};
|
|
2152
|
+
calculateLayout = () => {
|
|
2153
|
+
const flushLayoutObservers = (node) => {
|
|
2154
|
+
const observerEntries = /* @__PURE__ */ new Map();
|
|
2155
|
+
this.calculateScrollAndTriggerObservers(node, observerEntries);
|
|
2156
|
+
for (const [observer, entries] of observerEntries) {
|
|
2157
|
+
observer.internalTrigger(entries);
|
|
2158
|
+
}
|
|
2159
|
+
};
|
|
2160
|
+
this.prepareYogaTree(this.rootNode, flushLayoutObservers);
|
|
2161
|
+
const terminalWidth = getWindowSize(this.options.stdout).columns;
|
|
2162
|
+
this.rootNode.yogaNode.setWidth(terminalWidth);
|
|
2163
|
+
this.rootNode.yogaNode.calculateLayout(void 0, void 0, Yoga.DIRECTION_LTR);
|
|
2164
|
+
flushLayoutObservers(this.rootNode);
|
|
2165
|
+
};
|
|
2166
|
+
calculateScrollAndTriggerObservers(node, observerEntries) {
|
|
2167
|
+
if (node.nodeName === "ink-box") {
|
|
2168
|
+
const { style } = node;
|
|
2169
|
+
const overflow = style.overflow ?? "visible";
|
|
2170
|
+
const overflowX = style.overflowX ?? overflow;
|
|
2171
|
+
const overflowY = style.overflowY ?? overflow;
|
|
2172
|
+
if (overflowX === "scroll" || overflowY === "scroll") {
|
|
2173
|
+
calculateScroll(node);
|
|
2174
|
+
} else if (node.internal_scrollState) {
|
|
2175
|
+
delete node.internal_scrollState;
|
|
2176
|
+
}
|
|
2177
|
+
}
|
|
2178
|
+
measureAndExtractObservers(node, observerEntries);
|
|
2179
|
+
if (node.internal_static) {
|
|
2180
|
+
return;
|
|
2181
|
+
}
|
|
2182
|
+
for (const child of node.childNodes) {
|
|
2183
|
+
if (child.nodeName !== "#text") {
|
|
2184
|
+
this.calculateScrollAndTriggerObservers(child, observerEntries);
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
/**
|
|
2189
|
+
* Force a full layout recalculation by marking all text nodes dirty.
|
|
2190
|
+
* Useful when the string width function changes or terminal font changes.
|
|
2191
|
+
*/
|
|
2192
|
+
recalculateLayout() {
|
|
2193
|
+
this.markAllTextNodesDirty(this.rootNode);
|
|
2194
|
+
this.calculateLayout();
|
|
2195
|
+
this.onRender();
|
|
2196
|
+
}
|
|
2197
|
+
/**
|
|
2198
|
+
* Walk the DOM tree before Yoga layout to handle StaticRender nodes:
|
|
2199
|
+
* - Re-attach Yoga children if a cached render was invalidated
|
|
2200
|
+
* - Pre-render ink-static-render nodes that don't have a cached render yet
|
|
2201
|
+
*/
|
|
2202
|
+
prepareYogaTree(node, flushLayoutObservers) {
|
|
2203
|
+
if (node.isYogaTreeDetached && !node.cachedRender && node.yogaNode) {
|
|
2204
|
+
node.yogaNode.setWidthAuto();
|
|
2205
|
+
node.yogaNode.setHeightAuto();
|
|
2206
|
+
styles(node.yogaNode, node.style);
|
|
2207
|
+
while (node.yogaNode.getChildCount() > 0) {
|
|
2208
|
+
node.yogaNode.removeChild(node.yogaNode.getChild(0));
|
|
2209
|
+
}
|
|
2210
|
+
let yogaIndex = 0;
|
|
2211
|
+
for (const child of node.childNodes) {
|
|
2212
|
+
const domChild = child;
|
|
2213
|
+
if (child.nodeName !== "#text" && domChild.yogaNode) {
|
|
2214
|
+
node.yogaNode.insertChild(domChild.yogaNode, yogaIndex);
|
|
2215
|
+
yogaIndex++;
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
node.isYogaTreeDetached = false;
|
|
2219
|
+
this.markAllTextNodesDirty(node);
|
|
2220
|
+
}
|
|
2221
|
+
for (const child of node.childNodes) {
|
|
2222
|
+
if (child.nodeName !== "#text") {
|
|
2223
|
+
this.prepareYogaTree(child, flushLayoutObservers);
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
if (node.nodeName === "ink-static-render" && !node.cachedRender) {
|
|
2227
|
+
const terminalWidth = getWindowSize(this.options.stdout).columns;
|
|
2228
|
+
const { width } = node.style;
|
|
2229
|
+
if (node.yogaNode) {
|
|
2230
|
+
node.yogaNode.setWidth(typeof width === "number" ? width : terminalWidth);
|
|
2231
|
+
node.yogaNode.calculateLayout(void 0, void 0, Yoga.DIRECTION_LTR);
|
|
2232
|
+
}
|
|
2233
|
+
flushLayoutObservers(node);
|
|
2234
|
+
renderToStatic(node, {
|
|
2235
|
+
skipStaticElements: false});
|
|
2236
|
+
node.internal_onRendered?.();
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
markAllTextNodesDirty(node) {
|
|
2240
|
+
if (node.cachedRender) {
|
|
2241
|
+
return;
|
|
2242
|
+
}
|
|
2243
|
+
if (node.nodeName === "ink-text" && node.yogaNode) {
|
|
2244
|
+
node.yogaNode.markDirty();
|
|
2245
|
+
}
|
|
2246
|
+
for (const child of node.childNodes) {
|
|
2247
|
+
if (child.nodeName !== "#text") {
|
|
2248
|
+
this.markAllTextNodesDirty(child);
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
onRender = () => {
|
|
2253
|
+
this.hasPendingThrottledRender = false;
|
|
2254
|
+
if (this.isUnmounted) {
|
|
2255
|
+
return;
|
|
2256
|
+
}
|
|
2257
|
+
if (!this.deferredInitDone) {
|
|
2258
|
+
this.runDeferredInit();
|
|
2259
|
+
}
|
|
2260
|
+
if (this.nextRenderCommit) {
|
|
2261
|
+
this.nextRenderCommit.resolve();
|
|
2262
|
+
this.nextRenderCommit = void 0;
|
|
2263
|
+
}
|
|
2264
|
+
const renderResult = renderer(this.rootNode, this.isScreenReaderEnabled, {
|
|
2265
|
+
useNativeRenderer: this.useNativeRenderer
|
|
2266
|
+
});
|
|
2267
|
+
const { cursorPosition, cursorRequested, output, outputBuffer, outputHeight, outputWidth, staticOutput } = renderResult;
|
|
2268
|
+
this.renderedCursorRequested = cursorRequested;
|
|
2269
|
+
this.renderedCursorPosition = cursorPosition;
|
|
2270
|
+
if (this.useNativeRenderer && this.nativeLog && outputBuffer && outputWidth) {
|
|
2271
|
+
if (staticOutput && staticOutput !== "\n") {
|
|
2272
|
+
this.options.stdout.write(staticOutput);
|
|
2273
|
+
}
|
|
2274
|
+
this.nativeLog.render(outputBuffer, outputWidth, outputHeight);
|
|
2275
|
+
this.lastOutputHeight = outputHeight;
|
|
2276
|
+
return;
|
|
2277
|
+
}
|
|
2278
|
+
if (cursorRequested) {
|
|
2279
|
+
this.log.setCursorPosition(this.getActiveCursorPosition());
|
|
2280
|
+
}
|
|
2281
|
+
const hasStaticOutput = staticOutput && staticOutput !== "\n";
|
|
2282
|
+
if (this.options.debug) {
|
|
2283
|
+
if (hasStaticOutput) {
|
|
2284
|
+
this.fullStaticOutput += staticOutput;
|
|
2285
|
+
}
|
|
2286
|
+
this.lastOutput = output;
|
|
2287
|
+
this.lastOutputToRender = output;
|
|
2288
|
+
this.lastOutputHeight = outputHeight;
|
|
2289
|
+
this.options.stdout.write(this.fullStaticOutput + output);
|
|
2290
|
+
return;
|
|
2291
|
+
}
|
|
2292
|
+
if (!this.interactive) {
|
|
2293
|
+
if (hasStaticOutput) {
|
|
2294
|
+
this.options.stdout.write(staticOutput);
|
|
2295
|
+
}
|
|
2296
|
+
this.lastOutput = output;
|
|
2297
|
+
this.lastOutputToRender = `${output}
|
|
2298
|
+
`;
|
|
2299
|
+
this.lastOutputHeight = outputHeight;
|
|
2300
|
+
return;
|
|
2301
|
+
}
|
|
2302
|
+
if (this.isScreenReaderEnabled) {
|
|
2303
|
+
const sync = this.shouldSync();
|
|
2304
|
+
if (sync) {
|
|
2305
|
+
this.options.stdout.write(bsu);
|
|
2306
|
+
}
|
|
2307
|
+
if (hasStaticOutput) {
|
|
2308
|
+
const erase = this.lastOutputHeight > 0 ? eraseLines(this.lastOutputHeight) : "";
|
|
2309
|
+
this.options.stdout.write(erase + staticOutput);
|
|
2310
|
+
this.lastOutputHeight = 0;
|
|
2311
|
+
}
|
|
2312
|
+
if (output === this.lastOutput && !hasStaticOutput) {
|
|
2313
|
+
if (sync) {
|
|
2314
|
+
this.options.stdout.write(esu);
|
|
2315
|
+
}
|
|
2316
|
+
return;
|
|
2317
|
+
}
|
|
2318
|
+
const terminalWidth = getWindowSize(this.options.stdout).columns;
|
|
2319
|
+
const wrappedOutput = wordWrap(output, {
|
|
2320
|
+
trim: false,
|
|
2321
|
+
width: terminalWidth,
|
|
2322
|
+
wrapMode: "BREAK_WORDS"
|
|
2323
|
+
}).replace(/\n$/, "");
|
|
2324
|
+
if (hasStaticOutput) {
|
|
2325
|
+
this.options.stdout.write(wrappedOutput);
|
|
2326
|
+
} else {
|
|
2327
|
+
const erase = this.lastOutputHeight > 0 ? eraseLines(this.lastOutputHeight) : "";
|
|
2328
|
+
this.options.stdout.write(erase + wrappedOutput);
|
|
2329
|
+
}
|
|
2330
|
+
this.lastOutput = output;
|
|
2331
|
+
this.lastOutputToRender = wrappedOutput;
|
|
2332
|
+
this.lastOutputHeight = wrappedOutput === "" ? 0 : wrappedOutput.split("\n").length;
|
|
2333
|
+
if (sync) {
|
|
2334
|
+
this.options.stdout.write(esu);
|
|
2335
|
+
}
|
|
2336
|
+
return;
|
|
2337
|
+
}
|
|
2338
|
+
if (hasStaticOutput) {
|
|
2339
|
+
this.fullStaticOutput += staticOutput;
|
|
2340
|
+
}
|
|
2341
|
+
this.renderInteractiveFrame(output, outputHeight, hasStaticOutput ? staticOutput : "");
|
|
2342
|
+
};
|
|
2343
|
+
// Cache AccessibilityContext value to avoid creating a new object
|
|
2344
|
+
// on every render() call, which would force all consumers to re-render.
|
|
2345
|
+
accessibilityContextValue;
|
|
2346
|
+
render(node) {
|
|
2347
|
+
this.accessibilityContextValue ??= { isScreenReaderEnabled: this.isScreenReaderEnabled };
|
|
2348
|
+
const tree = jsx(accessibilityContext.Provider, { value: this.accessibilityContextValue, children: jsx(
|
|
2349
|
+
App,
|
|
2350
|
+
{
|
|
2351
|
+
exitOnCtrlC: this.options.exitOnCtrlC,
|
|
2352
|
+
interactive: this.interactive,
|
|
2353
|
+
onExit: this.handleAppExit,
|
|
2354
|
+
onWaitUntilRenderFlush: this.waitUntilRenderFlush,
|
|
2355
|
+
renderThrottleMs: this.renderThrottleMs,
|
|
2356
|
+
setCursorPosition: this.setCursorPosition,
|
|
2357
|
+
stderr: this.options.stderr,
|
|
2358
|
+
stdin: this.options.stdin,
|
|
2359
|
+
stdout: this.options.stdout,
|
|
2360
|
+
writeToStderr: this.writeToStderr,
|
|
2361
|
+
writeToStdout: this.writeToStdout,
|
|
2362
|
+
children: node
|
|
2363
|
+
}
|
|
2364
|
+
) });
|
|
2365
|
+
if (this.options.concurrent) {
|
|
2366
|
+
reconcilerInstance.updateContainer(tree, this.container, null, noop);
|
|
2367
|
+
} else {
|
|
2368
|
+
reconcilerInstance.updateContainerSync(tree, this.container, null, noop);
|
|
2369
|
+
reconcilerInstance.flushSyncWork();
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
writeToStdout = (data) => {
|
|
2373
|
+
if (this.isUnmounted) {
|
|
2374
|
+
return;
|
|
2375
|
+
}
|
|
2376
|
+
if (this.options.debug) {
|
|
2377
|
+
this.options.stdout.write(data + this.fullStaticOutput + this.lastOutput);
|
|
2378
|
+
return;
|
|
2379
|
+
}
|
|
2380
|
+
if (!this.interactive) {
|
|
2381
|
+
this.options.stdout.write(data);
|
|
2382
|
+
return;
|
|
2383
|
+
}
|
|
2384
|
+
const sync = this.shouldSync();
|
|
2385
|
+
if (sync) {
|
|
2386
|
+
this.options.stdout.write(bsu);
|
|
2387
|
+
}
|
|
2388
|
+
this.log.clear();
|
|
2389
|
+
this.options.stdout.write(data);
|
|
2390
|
+
this.restoreLastOutput();
|
|
2391
|
+
if (sync) {
|
|
2392
|
+
this.options.stdout.write(esu);
|
|
2393
|
+
}
|
|
2394
|
+
};
|
|
2395
|
+
writeToStderr = (data) => {
|
|
2396
|
+
if (this.isUnmounted) {
|
|
2397
|
+
return;
|
|
2398
|
+
}
|
|
2399
|
+
if (this.options.debug) {
|
|
2400
|
+
this.options.stderr.write(data);
|
|
2401
|
+
this.options.stdout.write(this.fullStaticOutput + this.lastOutput);
|
|
2402
|
+
return;
|
|
2403
|
+
}
|
|
2404
|
+
if (!this.interactive) {
|
|
2405
|
+
this.options.stderr.write(data);
|
|
2406
|
+
return;
|
|
2407
|
+
}
|
|
2408
|
+
const sync = this.shouldSync();
|
|
2409
|
+
if (sync) {
|
|
2410
|
+
this.options.stdout.write(bsu);
|
|
2411
|
+
}
|
|
2412
|
+
this.log.clear();
|
|
2413
|
+
this.options.stderr.write(data);
|
|
2414
|
+
this.restoreLastOutput();
|
|
2415
|
+
if (sync) {
|
|
2416
|
+
this.options.stdout.write(esu);
|
|
2417
|
+
}
|
|
2418
|
+
};
|
|
2419
|
+
unmount = (error) => {
|
|
2420
|
+
if (this.isUnmounted || this.isUnmounting) {
|
|
2421
|
+
return;
|
|
2422
|
+
}
|
|
2423
|
+
this.isUnmounting = true;
|
|
2424
|
+
if (this.beforeExitHandler) {
|
|
2425
|
+
process$2.off("beforeExit", this.beforeExitHandler);
|
|
2426
|
+
this.beforeExitHandler = void 0;
|
|
2427
|
+
}
|
|
2428
|
+
const stdout = this.options.stdout;
|
|
2429
|
+
const { canWriteToStdout, hasWritableState } = getWritableStreamState(stdout);
|
|
2430
|
+
settleThrottle(this.throttledOnRender, canWriteToStdout);
|
|
2431
|
+
if (canWriteToStdout && !this.alternateScreen) {
|
|
2432
|
+
const shouldRenderFinalFrame = !this.throttledOnRender || !this.hasPendingThrottledRender && this.fullStaticOutput === "";
|
|
2433
|
+
if (shouldRenderFinalFrame) {
|
|
2434
|
+
this.calculateLayout();
|
|
2435
|
+
this.onRender();
|
|
2436
|
+
}
|
|
2437
|
+
}
|
|
2438
|
+
this.isUnmounted = true;
|
|
2439
|
+
this.unsubscribeExit();
|
|
2440
|
+
settleThrottle(this.throttledLog, canWriteToStdout);
|
|
2441
|
+
if (typeof this.restoreConsole === "function") {
|
|
2442
|
+
this.restoreConsole();
|
|
2443
|
+
}
|
|
2444
|
+
const finishUnmount = () => {
|
|
2445
|
+
if (typeof this.unsubscribeResize === "function") {
|
|
2446
|
+
this.unsubscribeResize();
|
|
2447
|
+
}
|
|
2448
|
+
if (this.cancelKittyDetection) {
|
|
2449
|
+
this.cancelKittyDetection();
|
|
2450
|
+
}
|
|
2451
|
+
if (canWriteToStdout) {
|
|
2452
|
+
if (this.kittyProtocolEnabled) {
|
|
2453
|
+
this.writeBestEffort(this.options.stdout, "\x1B[<u");
|
|
2454
|
+
}
|
|
2455
|
+
if (this.alternateScreen) {
|
|
2456
|
+
this.log.clear();
|
|
2457
|
+
this.log.done();
|
|
2458
|
+
this.lastOutput = "";
|
|
2459
|
+
this.lastOutputToRender = "";
|
|
2460
|
+
this.lastOutputHeight = 0;
|
|
2461
|
+
this.fullStaticOutput = "";
|
|
2462
|
+
this.writeBestEffort(this.options.stdout, ALT_SCREEN_OFF);
|
|
2463
|
+
this.writeBestEffort(this.options.stdout, showCursorEscape);
|
|
2464
|
+
this.alternateScreen = false;
|
|
2465
|
+
} else if (!this.interactive) {
|
|
2466
|
+
this.options.stdout.write(this.options.debug ? "\n" : `${this.lastOutput}
|
|
2467
|
+
`);
|
|
2468
|
+
} else if (!this.options.debug) {
|
|
2469
|
+
this.log.done();
|
|
2470
|
+
}
|
|
2471
|
+
}
|
|
2472
|
+
this.kittyProtocolEnabled = false;
|
|
2473
|
+
instances.delete(this.options.stdout);
|
|
2474
|
+
const { exitResult } = this;
|
|
2475
|
+
const resolveOrReject = () => {
|
|
2476
|
+
if (isErrorInput(error)) {
|
|
2477
|
+
this.rejectExitPromise(error);
|
|
2478
|
+
} else {
|
|
2479
|
+
this.resolveExitPromise(exitResult);
|
|
2480
|
+
}
|
|
2481
|
+
};
|
|
2482
|
+
const isProcessExiting = error !== void 0 && !isErrorInput(error);
|
|
2483
|
+
if (isProcessExiting) {
|
|
2484
|
+
resolveOrReject();
|
|
2485
|
+
} else if (canWriteToStdout && hasWritableState) {
|
|
2486
|
+
this.options.stdout.write("", resolveOrReject);
|
|
2487
|
+
} else {
|
|
2488
|
+
setImmediate(resolveOrReject);
|
|
2489
|
+
}
|
|
2490
|
+
};
|
|
2491
|
+
const concurrentReconciler = reconcilerInstance;
|
|
2492
|
+
if (this.options.concurrent) {
|
|
2493
|
+
reconcilerInstance.updateContainerSync(null, this.container, null, noop);
|
|
2494
|
+
reconcilerInstance.flushSyncWork();
|
|
2495
|
+
concurrentReconciler.flushPassiveEffects?.();
|
|
2496
|
+
finishUnmount();
|
|
2497
|
+
} else {
|
|
2498
|
+
reconcilerInstance.updateContainerSync(null, this.container, null, noop);
|
|
2499
|
+
reconcilerInstance.flushSyncWork();
|
|
2500
|
+
finishUnmount();
|
|
2501
|
+
}
|
|
2502
|
+
};
|
|
2503
|
+
async waitUntilExit() {
|
|
2504
|
+
if (!this.beforeExitHandler) {
|
|
2505
|
+
this.beforeExitHandler = () => {
|
|
2506
|
+
this.unmount();
|
|
2507
|
+
};
|
|
2508
|
+
process$2.on("beforeExit", this.beforeExitHandler);
|
|
2509
|
+
}
|
|
2510
|
+
return this.exitPromise;
|
|
2511
|
+
}
|
|
2512
|
+
async waitUntilRenderFlush() {
|
|
2513
|
+
if (this.isUnmounted || this.isUnmounting) {
|
|
2514
|
+
await this.awaitExit();
|
|
2515
|
+
return;
|
|
2516
|
+
}
|
|
2517
|
+
await yieldImmediate();
|
|
2518
|
+
if (this.isUnmounted || this.isUnmounting) {
|
|
2519
|
+
await this.awaitExit();
|
|
2520
|
+
return;
|
|
2521
|
+
}
|
|
2522
|
+
if (this.isConcurrent && this.hasPendingConcurrentWork()) {
|
|
2523
|
+
await Promise.race([this.awaitNextRender(), this.awaitExit()]);
|
|
2524
|
+
if (this.isUnmounted || this.isUnmounting) {
|
|
2525
|
+
this.nextRenderCommit = void 0;
|
|
2526
|
+
await this.awaitExit();
|
|
2527
|
+
return;
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
reconcilerInstance.flushSyncWork();
|
|
2531
|
+
const stdout = this.options.stdout;
|
|
2532
|
+
const { canWriteToStdout, hasWritableState } = getWritableStreamState(stdout);
|
|
2533
|
+
settleThrottle(this.throttledOnRender, canWriteToStdout);
|
|
2534
|
+
settleThrottle(this.throttledLog, canWriteToStdout);
|
|
2535
|
+
if (canWriteToStdout && hasWritableState) {
|
|
2536
|
+
await new Promise((resolve) => {
|
|
2537
|
+
this.options.stdout.write("", () => {
|
|
2538
|
+
resolve();
|
|
2539
|
+
});
|
|
2540
|
+
});
|
|
2541
|
+
return;
|
|
2542
|
+
}
|
|
2543
|
+
await yieldImmediate();
|
|
2544
|
+
}
|
|
2545
|
+
clear() {
|
|
2546
|
+
if (this.interactive && !this.options.debug) {
|
|
2547
|
+
this.log.clear();
|
|
2548
|
+
this.log.sync(this.lastOutputToRender || `${this.lastOutput}
|
|
2549
|
+
`);
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
patchConsole() {
|
|
2553
|
+
if (this.options.debug) {
|
|
2554
|
+
return;
|
|
2555
|
+
}
|
|
2556
|
+
this.restoreConsole = patchConsole((stream, data) => {
|
|
2557
|
+
if (stream === "stdout") {
|
|
2558
|
+
this.writeToStdout(data);
|
|
2559
|
+
}
|
|
2560
|
+
if (stream === "stderr") {
|
|
2561
|
+
const isReactMessage = data.startsWith("The above error occurred");
|
|
2562
|
+
if (!isReactMessage) {
|
|
2563
|
+
this.writeToStderr(data);
|
|
2564
|
+
}
|
|
2565
|
+
}
|
|
2566
|
+
});
|
|
2567
|
+
}
|
|
2568
|
+
setAlternateScreen(enabled) {
|
|
2569
|
+
this.alternateScreen = this.resolveAlternateScreenOption(enabled, this.interactive);
|
|
2570
|
+
if (this.alternateScreen) {
|
|
2571
|
+
this.writeBestEffort(this.options.stdout, ALT_SCREEN_ON);
|
|
2572
|
+
this.writeBestEffort(this.options.stdout, hideCursorEscape);
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
resolveInteractiveOption(interactive) {
|
|
2576
|
+
return interactive ?? (!isInCi && Boolean(this.options.stdout.isTTY));
|
|
2577
|
+
}
|
|
2578
|
+
resolveAlternateScreenOption(alternateScreen, interactive) {
|
|
2579
|
+
return Boolean(alternateScreen) && interactive && Boolean(this.options.stdout.isTTY);
|
|
2580
|
+
}
|
|
2581
|
+
shouldSync() {
|
|
2582
|
+
return shouldSynchronize(this.options.stdout, this.interactive);
|
|
2583
|
+
}
|
|
2584
|
+
// Best-effort write: streams may already be destroyed during shutdown.
|
|
2585
|
+
writeBestEffort(stream, data) {
|
|
2586
|
+
try {
|
|
2587
|
+
stream.write(data);
|
|
2588
|
+
} catch {
|
|
2589
|
+
}
|
|
2590
|
+
}
|
|
2591
|
+
// Waits for the exit promise to settle, suppressing any rejection.
|
|
2592
|
+
// Errors are surfaced via waitUntilExit() instead.
|
|
2593
|
+
async awaitExit() {
|
|
2594
|
+
try {
|
|
2595
|
+
await this.exitPromise;
|
|
2596
|
+
} catch {
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
hasPendingConcurrentWork() {
|
|
2600
|
+
const concurrentContainer = this.container;
|
|
2601
|
+
return (concurrentContainer.pendingLanes ?? 0) !== 0 && concurrentContainer.callbackNode !== void 0 && concurrentContainer.callbackNode !== null;
|
|
2602
|
+
}
|
|
2603
|
+
async awaitNextRender() {
|
|
2604
|
+
if (!this.nextRenderCommit) {
|
|
2605
|
+
let resolveRender;
|
|
2606
|
+
const promise = new Promise((resolve) => {
|
|
2607
|
+
resolveRender = resolve;
|
|
2608
|
+
});
|
|
2609
|
+
this.nextRenderCommit = { promise, resolve: resolveRender };
|
|
2610
|
+
}
|
|
2611
|
+
return this.nextRenderCommit.promise;
|
|
2612
|
+
}
|
|
2613
|
+
renderInteractiveFrame(output, outputHeight, staticOutput) {
|
|
2614
|
+
const hasStaticOutput = staticOutput !== "";
|
|
2615
|
+
const isTty = this.options.stdout.isTTY;
|
|
2616
|
+
const viewportRows = isTty ? getWindowSize(this.options.stdout).rows : 24;
|
|
2617
|
+
const isFullscreen = isTty && outputHeight >= viewportRows;
|
|
2618
|
+
const outputToRender = isFullscreen ? output : `${output}
|
|
2619
|
+
`;
|
|
2620
|
+
const shouldClearTerminal = shouldClearTerminalForFrame({
|
|
2621
|
+
isTty,
|
|
2622
|
+
isUnmounting: this.isUnmounting,
|
|
2623
|
+
nextOutputHeight: outputHeight,
|
|
2624
|
+
previousOutputHeight: this.lastOutputHeight,
|
|
2625
|
+
viewportRows
|
|
2626
|
+
});
|
|
2627
|
+
if (shouldClearTerminal) {
|
|
2628
|
+
if (this.options.incrementalRendering) {
|
|
2629
|
+
if (hasStaticOutput) {
|
|
2630
|
+
this.log.clear();
|
|
2631
|
+
this.options.stdout.write(staticOutput);
|
|
2632
|
+
}
|
|
2633
|
+
if (output !== this.lastOutput || this.log.isCursorDirty() || hasStaticOutput) {
|
|
2634
|
+
this.throttledLog(outputToRender);
|
|
2635
|
+
}
|
|
2636
|
+
this.lastOutput = output;
|
|
2637
|
+
this.lastOutputToRender = outputToRender;
|
|
2638
|
+
this.lastOutputHeight = outputHeight;
|
|
2639
|
+
return;
|
|
2640
|
+
}
|
|
2641
|
+
const sync = this.shouldSync();
|
|
2642
|
+
if (sync) {
|
|
2643
|
+
this.options.stdout.write(bsu);
|
|
2644
|
+
}
|
|
2645
|
+
this.options.stdout.write(resetTerminal + this.fullStaticOutput + output);
|
|
2646
|
+
this.lastOutput = output;
|
|
2647
|
+
this.lastOutputToRender = outputToRender;
|
|
2648
|
+
this.lastOutputHeight = outputHeight;
|
|
2649
|
+
this.log.sync(outputToRender);
|
|
2650
|
+
if (sync) {
|
|
2651
|
+
this.options.stdout.write(esu);
|
|
2652
|
+
}
|
|
2653
|
+
return;
|
|
2654
|
+
}
|
|
2655
|
+
if (hasStaticOutput) {
|
|
2656
|
+
const sync = this.shouldSync();
|
|
2657
|
+
if (sync) {
|
|
2658
|
+
this.options.stdout.write(bsu);
|
|
2659
|
+
}
|
|
2660
|
+
this.log.clear();
|
|
2661
|
+
this.options.stdout.write(staticOutput);
|
|
2662
|
+
this.log(outputToRender);
|
|
2663
|
+
if (sync) {
|
|
2664
|
+
this.options.stdout.write(esu);
|
|
2665
|
+
}
|
|
2666
|
+
} else if (output !== this.lastOutput || this.log.isCursorDirty()) {
|
|
2667
|
+
this.throttledLog(outputToRender);
|
|
2668
|
+
}
|
|
2669
|
+
this.lastOutput = output;
|
|
2670
|
+
this.lastOutputToRender = outputToRender;
|
|
2671
|
+
this.lastOutputHeight = outputHeight;
|
|
2672
|
+
}
|
|
2673
|
+
/**
|
|
2674
|
+
* Handle kitty keyboard "enabled" mode immediately (just a stdout.write).
|
|
2675
|
+
* Called from the constructor.
|
|
2676
|
+
*/
|
|
2677
|
+
initImmediateKittyKeyboard() {
|
|
2678
|
+
if (!this.options.kittyKeyboard) {
|
|
2679
|
+
return;
|
|
2680
|
+
}
|
|
2681
|
+
const options = this.options.kittyKeyboard;
|
|
2682
|
+
const mode = options.mode ?? "auto";
|
|
2683
|
+
if (mode !== "enabled") {
|
|
2684
|
+
return;
|
|
2685
|
+
}
|
|
2686
|
+
const flags = options.flags ?? ["disambiguateEscapeCodes"];
|
|
2687
|
+
if (this.options.stdin.isTTY && this.options.stdout.isTTY) {
|
|
2688
|
+
this.enableKittyProtocol(flags);
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
/**
|
|
2692
|
+
* Handle kitty keyboard "auto" mode detection. Deferred to first render
|
|
2693
|
+
* because the CSI ? u query sets up a stdin listener with a 200ms timeout.
|
|
2694
|
+
*/
|
|
2695
|
+
initDeferredKittyKeyboard() {
|
|
2696
|
+
if (!this.options.kittyKeyboard) {
|
|
2697
|
+
return;
|
|
2698
|
+
}
|
|
2699
|
+
const options = this.options.kittyKeyboard;
|
|
2700
|
+
const mode = options.mode ?? "auto";
|
|
2701
|
+
if (mode !== "auto") {
|
|
2702
|
+
return;
|
|
2703
|
+
}
|
|
2704
|
+
const flags = options.flags ?? ["disambiguateEscapeCodes"];
|
|
2705
|
+
if (!this.interactive || !this.options.stdin.isTTY || !this.options.stdout.isTTY) {
|
|
2706
|
+
return;
|
|
2707
|
+
}
|
|
2708
|
+
this.confirmKittySupport(flags);
|
|
2709
|
+
}
|
|
2710
|
+
confirmKittySupport(flags) {
|
|
2711
|
+
const { stdin, stdout } = this.options;
|
|
2712
|
+
let responseBuffer = [];
|
|
2713
|
+
const cleanup = () => {
|
|
2714
|
+
this.cancelKittyDetection = void 0;
|
|
2715
|
+
clearTimeout(timer);
|
|
2716
|
+
stdin.removeListener("data", onData);
|
|
2717
|
+
const remaining = stripKittyQueryResponsesAndTrailingPartial(responseBuffer);
|
|
2718
|
+
responseBuffer = [];
|
|
2719
|
+
if (remaining.length > 0) {
|
|
2720
|
+
stdin.unshift(Buffer.from(remaining));
|
|
2721
|
+
}
|
|
2722
|
+
};
|
|
2723
|
+
const onData = (data) => {
|
|
2724
|
+
const chunk = typeof data === "string" ? Buffer.from(data) : data;
|
|
2725
|
+
for (const byte of chunk) {
|
|
2726
|
+
responseBuffer.push(byte);
|
|
2727
|
+
}
|
|
2728
|
+
if (hasCompleteKittyQueryResponse(responseBuffer)) {
|
|
2729
|
+
cleanup();
|
|
2730
|
+
if (!this.isUnmounted) {
|
|
2731
|
+
this.enableKittyProtocol(flags);
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
};
|
|
2735
|
+
stdin.on("data", onData);
|
|
2736
|
+
const timer = setTimeout(cleanup, 200);
|
|
2737
|
+
this.cancelKittyDetection = cleanup;
|
|
2738
|
+
stdout.write("\x1B[?u");
|
|
2739
|
+
}
|
|
2740
|
+
enableKittyProtocol(flags) {
|
|
2741
|
+
this.options.stdout.write(`\x1B[>${resolveFlags(flags)}u`);
|
|
2742
|
+
this.kittyProtocolEnabled = true;
|
|
2743
|
+
}
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
const render = (node, options) => {
|
|
2747
|
+
const inkOptions = {
|
|
2748
|
+
alternateScreen: false,
|
|
2749
|
+
concurrent: false,
|
|
2750
|
+
debug: false,
|
|
2751
|
+
exitOnCtrlC: true,
|
|
2752
|
+
incrementalRendering: false,
|
|
2753
|
+
maxFps: 30,
|
|
2754
|
+
patchConsole: true,
|
|
2755
|
+
stderr: process$2.stderr,
|
|
2756
|
+
stdin: process$2.stdin,
|
|
2757
|
+
stdout: process$2.stdout,
|
|
2758
|
+
...getOptions(options)
|
|
2759
|
+
};
|
|
2760
|
+
const instance = getInstance(inkOptions.stdout, () => new Ink(inkOptions));
|
|
2761
|
+
instance.render(node);
|
|
2762
|
+
return {
|
|
2763
|
+
cleanup() {
|
|
2764
|
+
instance.unmount();
|
|
2765
|
+
},
|
|
2766
|
+
clear() {
|
|
2767
|
+
instance.clear();
|
|
2768
|
+
},
|
|
2769
|
+
rerender(n) {
|
|
2770
|
+
instance.render(n);
|
|
2771
|
+
},
|
|
2772
|
+
rootNode: instance.rootNode,
|
|
2773
|
+
unmount() {
|
|
2774
|
+
instance.unmount();
|
|
2775
|
+
},
|
|
2776
|
+
waitUntilExit() {
|
|
2777
|
+
return instance.waitUntilExit();
|
|
2778
|
+
},
|
|
2779
|
+
waitUntilRenderFlush() {
|
|
2780
|
+
return instance.waitUntilRenderFlush();
|
|
2781
|
+
}
|
|
2782
|
+
};
|
|
2783
|
+
};
|
|
2784
|
+
const getOptions = (stdout = {}) => {
|
|
2785
|
+
if (stdout instanceof Stream) {
|
|
2786
|
+
return {
|
|
2787
|
+
stdin: process$2.stdin,
|
|
2788
|
+
stdout
|
|
2789
|
+
};
|
|
2790
|
+
}
|
|
2791
|
+
return stdout;
|
|
2792
|
+
};
|
|
2793
|
+
const getInstance = (stdout, createInstance) => {
|
|
2794
|
+
const instance = instances.get(stdout);
|
|
2795
|
+
if (instance === void 0) {
|
|
2796
|
+
const newInstance = createInstance();
|
|
2797
|
+
instances.set(stdout, newInstance);
|
|
2798
|
+
return newInstance;
|
|
2799
|
+
}
|
|
2800
|
+
process$2.stderr.write(
|
|
2801
|
+
"Warning: render() was called again for the same stdout before the previous Ink instance was unmounted. Reusing stdout across multiple render() calls is unsupported. Call unmount() first.\n"
|
|
2802
|
+
);
|
|
2803
|
+
return instance;
|
|
2804
|
+
};
|
|
2805
|
+
|
|
2806
|
+
export { render as default };
|