tinky 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/App.js +6 -6
- package/lib/components/Box.d.ts +2 -2
- package/lib/components/Box.js +2 -2
- package/lib/components/Static.d.ts +1 -1
- package/lib/components/Text.d.ts +1 -1
- package/lib/components/Text.js +3 -3
- package/lib/components/Transform.js +1 -1
- package/lib/{dom.js → core/dom.js} +3 -3
- package/lib/{log-update.js → core/log-update.js} +1 -1
- package/lib/{output.d.ts → core/output.d.ts} +1 -1
- package/lib/{render-border.js → core/render-border.js} +1 -1
- package/lib/{render-node-to-output.js → core/render-node-to-output.js} +4 -4
- package/lib/{tinky.js → core/tinky.js} +12 -12
- package/lib/hooks/use-app.js +1 -1
- package/lib/hooks/use-focus-manager.d.ts +1 -1
- package/lib/hooks/use-focus-manager.js +1 -1
- package/lib/hooks/use-focus.js +1 -1
- package/lib/hooks/use-input.js +2 -2
- package/lib/hooks/use-is-screen-reader-enabled.js +1 -1
- package/lib/hooks/use-stderr.js +1 -1
- package/lib/hooks/use-stdin.js +1 -1
- package/lib/hooks/use-stdout.js +1 -1
- package/lib/index.d.ts +12 -12
- package/lib/index.js +6 -6
- package/lib/utils/check-ci.d.ts +10 -0
- package/lib/utils/check-ci.js +21 -0
- package/lib/utils/cli-cursor.d.ts +20 -0
- package/lib/utils/cli-cursor.js +35 -0
- package/lib/{measure-element.d.ts → utils/measure-element.d.ts} +1 -1
- package/lib/utils/patch-console.d.ts +34 -0
- package/lib/utils/patch-console.js +83 -0
- package/lib/{render-background.d.ts → utils/render-background.d.ts} +2 -2
- package/lib/utils/signal-exit.d.ts +15 -0
- package/lib/utils/signal-exit.js +62 -0
- package/lib/{squash-text-nodes.d.ts → utils/squash-text-nodes.d.ts} +1 -1
- package/lib/{wrap-text.d.ts → utils/wrap-text.d.ts} +1 -1
- package/package.json +2 -5
- package/lib/signal-exit.d.ts +0 -11
- package/lib/signal-exit.js +0 -24
- /package/lib/{components → contexts}/AccessibilityContext.d.ts +0 -0
- /package/lib/{components → contexts}/AccessibilityContext.js +0 -0
- /package/lib/{components → contexts}/AppContext.d.ts +0 -0
- /package/lib/{components → contexts}/AppContext.js +0 -0
- /package/lib/{components → contexts}/BackgroundContext.d.ts +0 -0
- /package/lib/{components → contexts}/BackgroundContext.js +0 -0
- /package/lib/{components → contexts}/FocusContext.d.ts +0 -0
- /package/lib/{components → contexts}/FocusContext.js +0 -0
- /package/lib/{components → contexts}/StderrContext.d.ts +0 -0
- /package/lib/{components → contexts}/StderrContext.js +0 -0
- /package/lib/{components → contexts}/StdinContext.d.ts +0 -0
- /package/lib/{components → contexts}/StdinContext.js +0 -0
- /package/lib/{components → contexts}/StdoutContext.d.ts +0 -0
- /package/lib/{components → contexts}/StdoutContext.js +0 -0
- /package/lib/{devtools-window-polyfill.d.ts → core/devtools-window-polyfill.d.ts} +0 -0
- /package/lib/{devtools-window-polyfill.js → core/devtools-window-polyfill.js} +0 -0
- /package/lib/{devtools.d.ts → core/devtools.d.ts} +0 -0
- /package/lib/{devtools.js → core/devtools.js} +0 -0
- /package/lib/{dom.d.ts → core/dom.d.ts} +0 -0
- /package/lib/{instances.d.ts → core/instances.d.ts} +0 -0
- /package/lib/{instances.js → core/instances.js} +0 -0
- /package/lib/{log-update.d.ts → core/log-update.d.ts} +0 -0
- /package/lib/{output.js → core/output.js} +0 -0
- /package/lib/{reconciler.d.ts → core/reconciler.d.ts} +0 -0
- /package/lib/{reconciler.js → core/reconciler.js} +0 -0
- /package/lib/{render-border.d.ts → core/render-border.d.ts} +0 -0
- /package/lib/{render-node-to-output.d.ts → core/render-node-to-output.d.ts} +0 -0
- /package/lib/{render.d.ts → core/render.d.ts} +0 -0
- /package/lib/{render.js → core/render.js} +0 -0
- /package/lib/{renderer.d.ts → core/renderer.d.ts} +0 -0
- /package/lib/{renderer.js → core/renderer.js} +0 -0
- /package/lib/{styles.d.ts → core/styles.d.ts} +0 -0
- /package/lib/{styles.js → core/styles.js} +0 -0
- /package/lib/{taffy-node.d.ts → core/taffy-node.d.ts} +0 -0
- /package/lib/{taffy-node.js → core/taffy-node.js} +0 -0
- /package/lib/{tinky.d.ts → core/tinky.d.ts} +0 -0
- /package/lib/{colorize.d.ts → utils/colorize.d.ts} +0 -0
- /package/lib/{colorize.js → utils/colorize.js} +0 -0
- /package/lib/{dimension.d.ts → utils/dimension.d.ts} +0 -0
- /package/lib/{dimension.js → utils/dimension.js} +0 -0
- /package/lib/{get-max-width.d.ts → utils/get-max-width.d.ts} +0 -0
- /package/lib/{get-max-width.js → utils/get-max-width.js} +0 -0
- /package/lib/{measure-element.js → utils/measure-element.js} +0 -0
- /package/lib/{measure-text.d.ts → utils/measure-text.d.ts} +0 -0
- /package/lib/{measure-text.js → utils/measure-text.js} +0 -0
- /package/lib/{parse-keypress.d.ts → utils/parse-keypress.d.ts} +0 -0
- /package/lib/{parse-keypress.js → utils/parse-keypress.js} +0 -0
- /package/lib/{render-background.js → utils/render-background.js} +0 -0
- /package/lib/{squash-text-nodes.js → utils/squash-text-nodes.js} +0 -0
- /package/lib/{wrap-text.js → utils/wrap-text.js} +0 -0
package/lib/components/App.js
CHANGED
|
@@ -2,12 +2,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { EventEmitter } from "node:events";
|
|
3
3
|
import process from "node:process";
|
|
4
4
|
import { PureComponent } from "react";
|
|
5
|
-
import cliCursor from "cli-cursor";
|
|
6
|
-
import { AppContext } from "
|
|
7
|
-
import { StdinContext } from "
|
|
8
|
-
import { StdoutContext } from "
|
|
9
|
-
import { StderrContext } from "
|
|
10
|
-
import { FocusContext } from "
|
|
5
|
+
import * as cliCursor from "../utils/cli-cursor.js";
|
|
6
|
+
import { AppContext } from "../contexts/AppContext.js";
|
|
7
|
+
import { StdinContext } from "../contexts/StdinContext.js";
|
|
8
|
+
import { StdoutContext } from "../contexts/StdoutContext.js";
|
|
9
|
+
import { StderrContext } from "../contexts/StderrContext.js";
|
|
10
|
+
import { FocusContext } from "../contexts/FocusContext.js";
|
|
11
11
|
import { ErrorOverview } from "./ErrorOverview.js";
|
|
12
12
|
const tab = "\t";
|
|
13
13
|
const shiftTab = "\u001B[Z";
|
package/lib/components/Box.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type Except } from "type-fest";
|
|
2
|
-
import { type Styles } from "../styles.js";
|
|
3
|
-
import { type DOMElement } from "../dom.js";
|
|
2
|
+
import { type Styles } from "../core/styles.js";
|
|
3
|
+
import { type DOMElement } from "../core/dom.js";
|
|
4
4
|
/**
|
|
5
5
|
* Props for the Box component.
|
|
6
6
|
*/
|
package/lib/components/Box.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useContext } from "react";
|
|
3
|
-
import { AccessibilityContext } from "
|
|
4
|
-
import { backgroundContext } from "
|
|
3
|
+
import { AccessibilityContext } from "../contexts/AccessibilityContext.js";
|
|
4
|
+
import { backgroundContext } from "../contexts/BackgroundContext.js";
|
|
5
5
|
/**
|
|
6
6
|
* `<Box>` is an essential Tinky component to build your layout. It's like
|
|
7
7
|
* `<div style="display: flex">` in the browser.
|
package/lib/components/Text.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
2
|
import { type ForegroundColorName } from "chalk";
|
|
3
3
|
import { type LiteralUnion } from "type-fest";
|
|
4
|
-
import { type Styles } from "../styles.js";
|
|
4
|
+
import { type Styles } from "../core/styles.js";
|
|
5
5
|
/**
|
|
6
6
|
* Props for the Text component.
|
|
7
7
|
*/
|
package/lib/components/Text.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useContext } from "react";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
-
import { colorize } from "../colorize.js";
|
|
5
|
-
import { AccessibilityContext } from "
|
|
6
|
-
import { backgroundContext } from "
|
|
4
|
+
import { colorize } from "../utils/colorize.js";
|
|
5
|
+
import { AccessibilityContext } from "../contexts/AccessibilityContext.js";
|
|
6
|
+
import { backgroundContext } from "../contexts/BackgroundContext.js";
|
|
7
7
|
/**
|
|
8
8
|
* This component can display text and change its style to make it bold,
|
|
9
9
|
* underlined, italic, or strikethrough.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useContext } from "react";
|
|
3
|
-
import { AccessibilityContext } from "
|
|
3
|
+
import { AccessibilityContext } from "../contexts/AccessibilityContext.js";
|
|
4
4
|
/**
|
|
5
5
|
* Transform a string representation of React components before they're written
|
|
6
6
|
* to output. For example, you might want to apply a gradient to text, add a
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import stringWidth from "string-width";
|
|
2
|
-
import { measureText } from "
|
|
3
|
-
import { wrapText } from "
|
|
4
|
-
import { squashTextNodes } from "
|
|
2
|
+
import { measureText } from "../utils/measure-text.js";
|
|
3
|
+
import { wrapText } from "../utils/wrap-text.js";
|
|
4
|
+
import { squashTextNodes } from "../utils/squash-text-nodes.js";
|
|
5
5
|
import { TaffyNode } from "./taffy-node.js";
|
|
6
6
|
/**
|
|
7
7
|
* Creates a new DOM element.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import cliBoxes from "cli-boxes";
|
|
2
2
|
import chalk from "chalk";
|
|
3
|
-
import { colorize } from "
|
|
3
|
+
import { colorize } from "../utils/colorize.js";
|
|
4
4
|
/**
|
|
5
5
|
* Renders the border for a DOM node.
|
|
6
6
|
* Calculates border dimensions and draws border characters with specified
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import widestLine from "widest-line";
|
|
2
2
|
import indentString from "indent-string";
|
|
3
3
|
import { Display } from "taffy-layout";
|
|
4
|
-
import { wrapText } from "
|
|
5
|
-
import { getMaxWidth } from "
|
|
6
|
-
import { squashTextNodes } from "
|
|
4
|
+
import { wrapText } from "../utils/wrap-text.js";
|
|
5
|
+
import { getMaxWidth } from "../utils/get-max-width.js";
|
|
6
|
+
import { squashTextNodes } from "../utils/squash-text-nodes.js";
|
|
7
7
|
import { renderBorder } from "./render-border.js";
|
|
8
|
-
import { renderBackground } from "
|
|
8
|
+
import { renderBackground } from "../utils/render-background.js";
|
|
9
9
|
/**
|
|
10
10
|
* Applies padding to text based on the layout of the first text node.
|
|
11
11
|
*
|
|
@@ -2,10 +2,10 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import { throttle } from "es-toolkit/compat";
|
|
4
4
|
import ansiEscapes from "ansi-escapes";
|
|
5
|
-
import
|
|
5
|
+
import { isCI } from "../utils/check-ci.js";
|
|
6
6
|
import autoBind from "auto-bind";
|
|
7
|
-
import { onExit } from "
|
|
8
|
-
import patchConsole from "patch-console";
|
|
7
|
+
import { onExit } from "../utils/signal-exit.js";
|
|
8
|
+
import { patchConsole } from "../utils/patch-console.js";
|
|
9
9
|
import { LegacyRoot } from "react-reconciler/constants.js";
|
|
10
10
|
import wrapAnsi from "wrap-ansi";
|
|
11
11
|
import { reconciler } from "./reconciler.js";
|
|
@@ -13,8 +13,8 @@ import { renderer } from "./renderer.js";
|
|
|
13
13
|
import * as dom from "./dom.js";
|
|
14
14
|
import { logUpdate } from "./log-update.js";
|
|
15
15
|
import { instances } from "./instances.js";
|
|
16
|
-
import { App } from "
|
|
17
|
-
import { AccessibilityContext } from "
|
|
16
|
+
import { App } from "../components/App.js";
|
|
17
|
+
import { AccessibilityContext } from "../contexts/AccessibilityContext.js";
|
|
18
18
|
const noop = () => {
|
|
19
19
|
// no-op
|
|
20
20
|
};
|
|
@@ -98,7 +98,7 @@ export class Tinky {
|
|
|
98
98
|
// Unmount when process exits
|
|
99
99
|
this.unsubscribeExit = onExit(() => {
|
|
100
100
|
this.unmount();
|
|
101
|
-
}
|
|
101
|
+
});
|
|
102
102
|
if (process.env["DEV"] === "true") {
|
|
103
103
|
reconciler.injectIntoDevTools({
|
|
104
104
|
bundleType: 0,
|
|
@@ -110,7 +110,7 @@ export class Tinky {
|
|
|
110
110
|
if (options.patchConsole) {
|
|
111
111
|
this.patchConsole();
|
|
112
112
|
}
|
|
113
|
-
if (!
|
|
113
|
+
if (!isCI) {
|
|
114
114
|
options.stdout.on("resize", this.resized);
|
|
115
115
|
this.unsubscribeResize = () => {
|
|
116
116
|
options.stdout.off("resize", this.resized);
|
|
@@ -197,7 +197,7 @@ export class Tinky {
|
|
|
197
197
|
this.options.stdout.write(this.fullStaticOutput + output);
|
|
198
198
|
return;
|
|
199
199
|
}
|
|
200
|
-
if (
|
|
200
|
+
if (isCI) {
|
|
201
201
|
if (hasStaticOutput) {
|
|
202
202
|
this.options.stdout.write(staticOutput);
|
|
203
203
|
}
|
|
@@ -284,7 +284,7 @@ export class Tinky {
|
|
|
284
284
|
this.options.stdout.write(data + this.fullStaticOutput + this.lastOutput);
|
|
285
285
|
return;
|
|
286
286
|
}
|
|
287
|
-
if (
|
|
287
|
+
if (isCI) {
|
|
288
288
|
this.options.stdout.write(data);
|
|
289
289
|
return;
|
|
290
290
|
}
|
|
@@ -306,7 +306,7 @@ export class Tinky {
|
|
|
306
306
|
this.options.stdout.write(this.fullStaticOutput + this.lastOutput);
|
|
307
307
|
return;
|
|
308
308
|
}
|
|
309
|
-
if (
|
|
309
|
+
if (isCI) {
|
|
310
310
|
this.options.stderr.write(data);
|
|
311
311
|
return;
|
|
312
312
|
}
|
|
@@ -338,7 +338,7 @@ export class Tinky {
|
|
|
338
338
|
}
|
|
339
339
|
// CIs don't handle erasing ansi escapes well, so it's better to
|
|
340
340
|
// only render last frame of non-static output
|
|
341
|
-
if (
|
|
341
|
+
if (isCI) {
|
|
342
342
|
this.options.stdout.write(this.lastOutput + "\n");
|
|
343
343
|
}
|
|
344
344
|
else if (!this.options.debug) {
|
|
@@ -382,7 +382,7 @@ export class Tinky {
|
|
|
382
382
|
* Clears the output.
|
|
383
383
|
*/
|
|
384
384
|
clear() {
|
|
385
|
-
if (!
|
|
385
|
+
if (!isCI && !this.options.debug) {
|
|
386
386
|
this.log.clear();
|
|
387
387
|
}
|
|
388
388
|
}
|
package/lib/hooks/use-app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useContext } from "react";
|
|
2
|
-
import { FocusContext } from "../
|
|
2
|
+
import { FocusContext } from "../contexts/FocusContext.js";
|
|
3
3
|
/**
|
|
4
4
|
* This hook exposes methods to enable or disable focus management for all
|
|
5
5
|
* components or manually switch focus to the next or previous components.
|
package/lib/hooks/use-focus.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useEffect, useContext, useMemo } from "react";
|
|
2
|
-
import { FocusContext } from "../
|
|
2
|
+
import { FocusContext } from "../contexts/FocusContext.js";
|
|
3
3
|
import { useStdin } from "./use-stdin.js";
|
|
4
4
|
/**
|
|
5
5
|
* A component that uses the `useFocus` hook becomes "focusable" to Tinky, so
|
package/lib/hooks/use-input.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect } from "react";
|
|
2
|
-
import { parseKeypress, nonAlphanumericKeys } from "../parse-keypress.js";
|
|
3
|
-
import { reconciler } from "../reconciler.js";
|
|
2
|
+
import { parseKeypress, nonAlphanumericKeys } from "../utils/parse-keypress.js";
|
|
3
|
+
import { reconciler } from "../core/reconciler.js";
|
|
4
4
|
import { useStdin } from "./use-stdin.js";
|
|
5
5
|
/**
|
|
6
6
|
* This hook is used for handling user input. It's a more convenient
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useContext } from "react";
|
|
2
|
-
import { AccessibilityContext } from "../
|
|
2
|
+
import { AccessibilityContext } from "../contexts/AccessibilityContext.js";
|
|
3
3
|
/**
|
|
4
4
|
* Returns whether a screen reader is enabled. This is useful when you want to
|
|
5
5
|
* render different output for screen readers.
|
package/lib/hooks/use-stderr.js
CHANGED
package/lib/hooks/use-stdin.js
CHANGED
package/lib/hooks/use-stdout.js
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { render, type RenderOptions, type Instance } from "./render.js";
|
|
1
|
+
export { render, type RenderOptions, type Instance } from "./core/render.js";
|
|
2
2
|
export { Box, type BoxProps } from "./components/Box.js";
|
|
3
3
|
export { Text, type TextProps } from "./components/Text.js";
|
|
4
|
-
export { AppContext, type AppProps } from "./
|
|
5
|
-
export { StdinContext, type StdinProps } from "./
|
|
6
|
-
export { StdoutContext, type StdoutProps } from "./
|
|
7
|
-
export { StderrContext, type StderrProps } from "./
|
|
4
|
+
export { AppContext, type AppProps } from "./contexts/AppContext.js";
|
|
5
|
+
export { StdinContext, type StdinProps } from "./contexts/StdinContext.js";
|
|
6
|
+
export { StdoutContext, type StdoutProps } from "./contexts/StdoutContext.js";
|
|
7
|
+
export { StderrContext, type StderrProps } from "./contexts/StderrContext.js";
|
|
8
8
|
export { Static, type StaticProps } from "./components/Static.js";
|
|
9
9
|
export { Transform, type TransformProps } from "./components/Transform.js";
|
|
10
10
|
export { Newline, type NewlineProps } from "./components/Newline.js";
|
|
@@ -17,10 +17,10 @@ export { useStderr } from "./hooks/use-stderr.js";
|
|
|
17
17
|
export { useFocus, type FocusOptions, type FocusState, } from "./hooks/use-focus.js";
|
|
18
18
|
export { useFocusManager, type FocusManager, } from "./hooks/use-focus-manager.js";
|
|
19
19
|
export { useIsScreenReaderEnabled } from "./hooks/use-is-screen-reader-enabled.js";
|
|
20
|
-
export { measureElement } from "./measure-element.js";
|
|
21
|
-
export { type Dimension } from "./dimension.js";
|
|
22
|
-
export { type DOMElement, type DOMNode, type DOMNodeAttribute, type ElementNames, type NodeNames, type TextName, type TextNode, type TinkyNode, } from "./dom.js";
|
|
23
|
-
export { type Styles } from "./styles.js";
|
|
24
|
-
export { type OutputTransformer } from "./render-node-to-output.js";
|
|
25
|
-
export { type RenderMetrics } from "./tinky.js";
|
|
26
|
-
export { type TaffyNode } from "./taffy-node.js";
|
|
20
|
+
export { measureElement } from "./utils/measure-element.js";
|
|
21
|
+
export { type Dimension } from "./utils/dimension.js";
|
|
22
|
+
export { type DOMElement, type DOMNode, type DOMNodeAttribute, type ElementNames, type NodeNames, type TextName, type TextNode, type TinkyNode, } from "./core/dom.js";
|
|
23
|
+
export { type Styles } from "./core/styles.js";
|
|
24
|
+
export { type OutputTransformer } from "./core/render-node-to-output.js";
|
|
25
|
+
export { type RenderMetrics } from "./core/tinky.js";
|
|
26
|
+
export { type TaffyNode } from "./core/taffy-node.js";
|
package/lib/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { render } from "./render.js";
|
|
1
|
+
export { render } from "./core/render.js";
|
|
2
2
|
export { Box } from "./components/Box.js";
|
|
3
3
|
export { Text } from "./components/Text.js";
|
|
4
|
-
export { AppContext } from "./
|
|
5
|
-
export { StdinContext } from "./
|
|
6
|
-
export { StdoutContext } from "./
|
|
7
|
-
export { StderrContext } from "./
|
|
4
|
+
export { AppContext } from "./contexts/AppContext.js";
|
|
5
|
+
export { StdinContext } from "./contexts/StdinContext.js";
|
|
6
|
+
export { StdoutContext } from "./contexts/StdoutContext.js";
|
|
7
|
+
export { StderrContext } from "./contexts/StderrContext.js";
|
|
8
8
|
export { Static } from "./components/Static.js";
|
|
9
9
|
export { Transform } from "./components/Transform.js";
|
|
10
10
|
export { Newline } from "./components/Newline.js";
|
|
@@ -17,4 +17,4 @@ export { useStderr } from "./hooks/use-stderr.js";
|
|
|
17
17
|
export { useFocus, } from "./hooks/use-focus.js";
|
|
18
18
|
export { useFocusManager, } from "./hooks/use-focus-manager.js";
|
|
19
19
|
export { useIsScreenReaderEnabled } from "./hooks/use-is-screen-reader-enabled.js";
|
|
20
|
-
export { measureElement } from "./measure-element.js";
|
|
20
|
+
export { measureElement } from "./utils/measure-element.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Determines if the current environment is a Continuous Integration (CI) environment.
|
|
3
|
+
*
|
|
4
|
+
* It checks for the presence of the `CI` or `CONTINUOUS_INTEGRATION` environment variables.
|
|
5
|
+
* These variables are commonly set by CI providers like GitHub Actions, Travis CI, CircleCI, etc.
|
|
6
|
+
*
|
|
7
|
+
* The check follows the convention that if the variable is present, it is considered true,
|
|
8
|
+
* unless explicitly set to '0' or 'false' (case-sensitive for the value check, though env vars are OS dependent).
|
|
9
|
+
*/
|
|
10
|
+
export declare const isCI: boolean;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
/**
|
|
3
|
+
* Checks if a specific environment variable is set and not explicitly disabled.
|
|
4
|
+
*
|
|
5
|
+
* @param key - The name of the environment variable to check.
|
|
6
|
+
* @returns `true` if the environment variable is set and its value is not '0' or 'false', otherwise `false`.
|
|
7
|
+
*/
|
|
8
|
+
const check = (key) => {
|
|
9
|
+
const value = process.env[key];
|
|
10
|
+
return value !== undefined && value !== "0" && value !== "false";
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Determines if the current environment is a Continuous Integration (CI) environment.
|
|
14
|
+
*
|
|
15
|
+
* It checks for the presence of the `CI` or `CONTINUOUS_INTEGRATION` environment variables.
|
|
16
|
+
* These variables are commonly set by CI providers like GitHub Actions, Travis CI, CircleCI, etc.
|
|
17
|
+
*
|
|
18
|
+
* The check follows the convention that if the variable is present, it is considered true,
|
|
19
|
+
* unless explicitly set to '0' or 'false' (case-sensitive for the value check, though env vars are OS dependent).
|
|
20
|
+
*/
|
|
21
|
+
export const isCI = check("CI") || check("CONTINUOUS_INTEGRATION");
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type Writable } from "node:stream";
|
|
2
|
+
/**
|
|
3
|
+
* Show the cursor.
|
|
4
|
+
*
|
|
5
|
+
* @param stream - The stream to show the cursor on. Defaults to `process.stderr`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function show(stream?: Writable): void;
|
|
8
|
+
/**
|
|
9
|
+
* Hide the cursor.
|
|
10
|
+
*
|
|
11
|
+
* @param stream - The stream to hide the cursor on. Defaults to `process.stderr`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function hide(stream?: Writable): void;
|
|
14
|
+
/**
|
|
15
|
+
* Toggle cursor visibility.
|
|
16
|
+
*
|
|
17
|
+
* @param force - If `true`, shows the cursor. If `false`, hides the cursor.
|
|
18
|
+
* @param stream - The stream to toggle the cursor on. Defaults to `process.stderr`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function toggle(force?: boolean, stream?: Writable): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
const kHideCursor = "\u001B[?25l";
|
|
3
|
+
const kShowCursor = "\u001B[?25h";
|
|
4
|
+
/**
|
|
5
|
+
* Show the cursor.
|
|
6
|
+
*
|
|
7
|
+
* @param stream - The stream to show the cursor on. Defaults to `process.stderr`.
|
|
8
|
+
*/
|
|
9
|
+
export function show(stream = process.stderr) {
|
|
10
|
+
stream.write(kShowCursor);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Hide the cursor.
|
|
14
|
+
*
|
|
15
|
+
* @param stream - The stream to hide the cursor on. Defaults to `process.stderr`.
|
|
16
|
+
*/
|
|
17
|
+
export function hide(stream = process.stderr) {
|
|
18
|
+
stream.write(kHideCursor);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Toggle cursor visibility.
|
|
22
|
+
*
|
|
23
|
+
* @param force - If `true`, shows the cursor. If `false`, hides the cursor.
|
|
24
|
+
* @param stream - The stream to toggle the cursor on. Defaults to `process.stderr`.
|
|
25
|
+
*/
|
|
26
|
+
export function toggle(force, stream = process.stderr) {
|
|
27
|
+
if (force !== undefined) {
|
|
28
|
+
if (force) {
|
|
29
|
+
show(stream);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
hide(stream);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Union type representing the standard output streams.
|
|
3
|
+
*/
|
|
4
|
+
type Stream = "stdout" | "stderr";
|
|
5
|
+
/**
|
|
6
|
+
* Callback function to handle intercepted console output.
|
|
7
|
+
*
|
|
8
|
+
* @param stream - The stream the output is intended for ('stdout' or 'stderr').
|
|
9
|
+
* @param data - The formatted string to be logged.
|
|
10
|
+
*/
|
|
11
|
+
type Callback = (stream: Stream, data: string) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Patches global console methods to intercept output and redirect it to a callback.
|
|
14
|
+
*
|
|
15
|
+
* This function wraps standard console methods (like `console.log`, `console.error`, etc.)
|
|
16
|
+
* so that they call the provided callback instead of writing directly to the stream.
|
|
17
|
+
* It uses `util.format` to format arguments exactly like the original console methods.
|
|
18
|
+
*
|
|
19
|
+
* @param callback - The function to call with the intercepted output.
|
|
20
|
+
* @returns A function that restores the original console methods when called.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* const restore = patchConsole((stream, data) => {
|
|
25
|
+
* console.log(`[${stream}] ${data}`);
|
|
26
|
+
* });
|
|
27
|
+
*
|
|
28
|
+
* console.log("Hello"); // Output: [stdout] Hello
|
|
29
|
+
*
|
|
30
|
+
* restore(); // Console is back to normal
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const patchConsole: (callback: Callback) => (() => void);
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import util from "util";
|
|
2
|
+
/**
|
|
3
|
+
* List of console methods to patch, categorized by their target stream.
|
|
4
|
+
*/
|
|
5
|
+
const METHODS = {
|
|
6
|
+
stdout: [
|
|
7
|
+
"log",
|
|
8
|
+
"info",
|
|
9
|
+
"dir",
|
|
10
|
+
"dirxml",
|
|
11
|
+
"table",
|
|
12
|
+
"count",
|
|
13
|
+
"countReset",
|
|
14
|
+
"group",
|
|
15
|
+
"groupCollapsed",
|
|
16
|
+
"groupEnd",
|
|
17
|
+
"time",
|
|
18
|
+
"timeLog",
|
|
19
|
+
"timeEnd",
|
|
20
|
+
"debug",
|
|
21
|
+
],
|
|
22
|
+
stderr: ["error", "warn", "trace", "assert"],
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Patches global console methods to intercept output and redirect it to a callback.
|
|
26
|
+
*
|
|
27
|
+
* This function wraps standard console methods (like `console.log`, `console.error`, etc.)
|
|
28
|
+
* so that they call the provided callback instead of writing directly to the stream.
|
|
29
|
+
* It uses `util.format` to format arguments exactly like the original console methods.
|
|
30
|
+
*
|
|
31
|
+
* @param callback - The function to call with the intercepted output.
|
|
32
|
+
* @returns A function that restores the original console methods when called.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const restore = patchConsole((stream, data) => {
|
|
37
|
+
* console.log(`[${stream}] ${data}`);
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* console.log("Hello"); // Output: [stdout] Hello
|
|
41
|
+
*
|
|
42
|
+
* restore(); // Console is back to normal
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export const patchConsole = (callback) => {
|
|
46
|
+
// Use ConsoleMethod to validly type the stored methods
|
|
47
|
+
const originalMethods = {};
|
|
48
|
+
const patch = (stream, method) => {
|
|
49
|
+
// Cast console to a record of ConsoleMethods to allow index access without explicit any
|
|
50
|
+
const consoleMethods = console;
|
|
51
|
+
originalMethods[method] = consoleMethods[method];
|
|
52
|
+
consoleMethods[method] = (...args) => {
|
|
53
|
+
// Handle console.assert specifically as it only outputs if assertion fails
|
|
54
|
+
if (method === "assert") {
|
|
55
|
+
if (!args[0]) {
|
|
56
|
+
// Remove the assertion condition and format the rest
|
|
57
|
+
callback(stream, util.format(...args.slice(1)));
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
callback(stream, util.format(...args));
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
for (const method of METHODS.stdout) {
|
|
65
|
+
if (console[method]) {
|
|
66
|
+
patch("stdout", method);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
for (const method of METHODS.stderr) {
|
|
70
|
+
if (console[method]) {
|
|
71
|
+
patch("stderr", method);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return () => {
|
|
75
|
+
// Cast console to a record of ConsoleMethods to restore original methods
|
|
76
|
+
const consoleMethods = console;
|
|
77
|
+
for (const [method, original] of Object.entries(originalMethods)) {
|
|
78
|
+
if (original) {
|
|
79
|
+
consoleMethods[method] = original;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type Callback = (code?: number | null, signal?: NodeJS.Signals | null) => void;
|
|
2
|
+
/**
|
|
3
|
+
* Registers a callback to be executed when the process exits or receives a termination signal.
|
|
4
|
+
*
|
|
5
|
+
* This function is an internal replacement for the `signal-exit` library.
|
|
6
|
+
* It ensures that the callback is executed when the process ends, whether naturally
|
|
7
|
+
* or via signals like SIGINT (Ctrl+C).
|
|
8
|
+
*
|
|
9
|
+
* @param callback - The function to call on exit.
|
|
10
|
+
* @param options - Configuration options.
|
|
11
|
+
* @param options.alwaysLast - (Ignored in this simplified implementation) Ensures callback runs after other exit handlers.
|
|
12
|
+
* @returns A function to unsubscribe the exit listener.
|
|
13
|
+
*/
|
|
14
|
+
export declare function onExit(callback: Callback): () => void;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import process from "node:process";
|
|
2
|
+
// Track all registered listeners
|
|
3
|
+
const callbacks = new Set();
|
|
4
|
+
let isAttached = false;
|
|
5
|
+
/**
|
|
6
|
+
* Handles signal events by invoking all registered callbacks and then exiting.
|
|
7
|
+
*
|
|
8
|
+
* @param signal - The signal that triggered the exit.
|
|
9
|
+
*/
|
|
10
|
+
const handleSignal = (signal) => {
|
|
11
|
+
for (const callback of callbacks) {
|
|
12
|
+
callback(null, signal);
|
|
13
|
+
}
|
|
14
|
+
// Restore default behavior: exit the process
|
|
15
|
+
// We need to exit explicitly because adding a listener prevents the default exit
|
|
16
|
+
process.exit(128 + 1);
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Handles the 'exit' event by invoking all registered callbacks.
|
|
20
|
+
*
|
|
21
|
+
* @param code - The exit code.
|
|
22
|
+
*/
|
|
23
|
+
const handleExit = (code) => {
|
|
24
|
+
for (const callback of callbacks) {
|
|
25
|
+
callback(code, null);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Attaches the global event listeners if they haven't been attached yet.
|
|
30
|
+
*/
|
|
31
|
+
const attach = () => {
|
|
32
|
+
if (isAttached) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
isAttached = true;
|
|
36
|
+
process.on("exit", handleExit);
|
|
37
|
+
process.on("SIGINT", handleSignal);
|
|
38
|
+
process.on("SIGTERM", handleSignal);
|
|
39
|
+
// SIGHUP is not supported on Windows, but safe to listen to on other platforms
|
|
40
|
+
if (process.platform !== "win32") {
|
|
41
|
+
process.on("SIGHUP", handleSignal);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
/**
|
|
45
|
+
* Registers a callback to be executed when the process exits or receives a termination signal.
|
|
46
|
+
*
|
|
47
|
+
* This function is an internal replacement for the `signal-exit` library.
|
|
48
|
+
* It ensures that the callback is executed when the process ends, whether naturally
|
|
49
|
+
* or via signals like SIGINT (Ctrl+C).
|
|
50
|
+
*
|
|
51
|
+
* @param callback - The function to call on exit.
|
|
52
|
+
* @param options - Configuration options.
|
|
53
|
+
* @param options.alwaysLast - (Ignored in this simplified implementation) Ensures callback runs after other exit handlers.
|
|
54
|
+
* @returns A function to unsubscribe the exit listener.
|
|
55
|
+
*/
|
|
56
|
+
export function onExit(callback) {
|
|
57
|
+
attach();
|
|
58
|
+
callbacks.add(callback);
|
|
59
|
+
return () => {
|
|
60
|
+
callbacks.delete(callback);
|
|
61
|
+
};
|
|
62
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tinky",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "React for CLIs, re-imagined with the Taffy engine",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -45,15 +45,11 @@
|
|
|
45
45
|
"auto-bind": "^5.0.1",
|
|
46
46
|
"chalk": "^5.6.2",
|
|
47
47
|
"cli-boxes": "^4.0.1",
|
|
48
|
-
"cli-cursor": "^5.0.0",
|
|
49
48
|
"cli-truncate": "^5.1.1",
|
|
50
49
|
"code-excerpt": "^4.0.0",
|
|
51
50
|
"es-toolkit": "^1.43.0",
|
|
52
51
|
"indent-string": "^5.0.0",
|
|
53
|
-
"is-in-ci": "^2.0.0",
|
|
54
|
-
"patch-console": "^2.0.0",
|
|
55
52
|
"react-reconciler": "^0.33.0",
|
|
56
|
-
"signal-exit": "^4.1.0",
|
|
57
53
|
"stack-utils": "^2.0.6",
|
|
58
54
|
"taffy-layout": "^0.1.0",
|
|
59
55
|
"tslint": "^5.20.1",
|
|
@@ -72,6 +68,7 @@
|
|
|
72
68
|
"@commitlint/config-conventional": "^20.3.0",
|
|
73
69
|
"@semantic-release/changelog": "^6.0.3",
|
|
74
70
|
"@semantic-release/git": "^10.0.1",
|
|
71
|
+
"@semantic-release/github": "^12.0.0",
|
|
75
72
|
"@semantic-release/npm": "^13.1.3",
|
|
76
73
|
"@sinonjs/fake-timers": "^15.1.0",
|
|
77
74
|
"@types/bun": "^1.3.6",
|
package/lib/signal-exit.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Registers a callback to be executed when the process exits or on signal.
|
|
3
|
-
*
|
|
4
|
-
* @param callback - The function to call on exit.
|
|
5
|
-
* @param options - Configuration options.
|
|
6
|
-
* @param options.alwaysLast - Ensures callback runs after other exit handlers.
|
|
7
|
-
* @returns A function to unsubscribe the exit listener.
|
|
8
|
-
*/
|
|
9
|
-
export declare function onExit(callback: (code?: number | null, signal?: NodeJS.Signals | null) => void, options?: {
|
|
10
|
-
alwaysLast?: boolean;
|
|
11
|
-
}): () => void;
|
package/lib/signal-exit.js
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import process from "node:process";
|
|
2
|
-
import { onExit as onSignalExit } from "signal-exit";
|
|
3
|
-
/**
|
|
4
|
-
* Registers a callback to be executed when the process exits or on signal.
|
|
5
|
-
*
|
|
6
|
-
* @param callback - The function to call on exit.
|
|
7
|
-
* @param options - Configuration options.
|
|
8
|
-
* @param options.alwaysLast - Ensures callback runs after other exit handlers.
|
|
9
|
-
* @returns A function to unsubscribe the exit listener.
|
|
10
|
-
*/
|
|
11
|
-
export function onExit(callback, options) {
|
|
12
|
-
const unsubscribeSignalExit = onSignalExit(callback, options);
|
|
13
|
-
// Polyfill for Bun: signal-exit does not seem to catch the 'exit' event
|
|
14
|
-
// in this specific test environment, so we attach a manual listener
|
|
15
|
-
// to ensure the final render frame is output.
|
|
16
|
-
const onProcessExit = (code) => {
|
|
17
|
-
callback(code, null);
|
|
18
|
-
};
|
|
19
|
-
process.on("exit", onProcessExit);
|
|
20
|
-
return () => {
|
|
21
|
-
unsubscribeSignalExit();
|
|
22
|
-
process.off("exit", onProcessExit);
|
|
23
|
-
};
|
|
24
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|