| export * from "./text"; | ||
| export * from "./input"; |
| "use strict"; | ||
| function __export(m) { | ||
| for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
| } | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| __export(require("./text")); | ||
| __export(require("./input")); |
| export declare const i: { | ||
| startPos: (input: { | ||
| position: { | ||
| x: number; | ||
| y: number; | ||
| }; | ||
| caretOffset: number; | ||
| length: number; | ||
| }) => { | ||
| x: number; | ||
| y: number; | ||
| }; | ||
| currentPos: (input: { | ||
| position: { | ||
| x: number; | ||
| y: number; | ||
| }; | ||
| caretOffset: number; | ||
| length: number; | ||
| }) => { | ||
| x: number; | ||
| y: number; | ||
| }; | ||
| endPos: (input: { | ||
| position: { | ||
| x: number; | ||
| y: number; | ||
| }; | ||
| caretOffset: number; | ||
| length: number; | ||
| }) => { | ||
| x: number; | ||
| y: number; | ||
| }; | ||
| }; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const startPos = (input) => input.position; | ||
| const currentPos = (input) => ({ | ||
| x: input.position.x + input.caretOffset, | ||
| y: input.position.y | ||
| }); | ||
| const endPos = (input) => ({ | ||
| x: input.position.x + input.length, | ||
| y: input.position.y | ||
| }); | ||
| exports.i = { | ||
| startPos, | ||
| currentPos, | ||
| endPos | ||
| }; |
| export declare const t: { | ||
| offsetAt: (text: string, { x, y }: { | ||
| x: number; | ||
| y: number; | ||
| }) => number; | ||
| slice: (text: string, start: { | ||
| x: number; | ||
| y: number; | ||
| }, end: { | ||
| x: number; | ||
| y: number; | ||
| }) => string; | ||
| splice: (text: string, start: { | ||
| x: number; | ||
| y: number; | ||
| }, deleteOffset: number, insert?: string) => string; | ||
| }; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const offsetAt = (text, { x, y }) => x + | ||
| text | ||
| /* .split(/(?<=\n)/) lookbehind is not transpilable xD */ | ||
| .split("\n") | ||
| .flatMap((x, i, xs) => x === "" && i === xs.length - 1 | ||
| ? [] | ||
| : [x + "\n"]) | ||
| .slice(0, y) | ||
| .reduce((a, s) => a + s.length, 0); | ||
| const slice = (text, start, end) => text.slice(offsetAt(text, start), offsetAt(text, end)); | ||
| const splice = (text, start, deleteOffset, insert = "") => { | ||
| let chars = text.split(""); | ||
| chars.splice(offsetAt(text, start) + (deleteOffset < 0 ? deleteOffset : 0), Math.abs(deleteOffset), ...insert.split("")); | ||
| return chars.join(""); | ||
| }; | ||
| exports.t = { | ||
| offsetAt, | ||
| slice, | ||
| splice | ||
| }; |
| export * from "./reducers"; | ||
| export * from "./derivers"; | ||
| export * from "./terminal"; | ||
| export * from "./recipes"; | ||
| export * from "./types"; |
| "use strict"; | ||
| function __export(m) { | ||
| for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
| } | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| __export(require("./reducers")); | ||
| __export(require("./derivers")); | ||
| __export(require("./terminal")); | ||
| __export(require("./recipes")); |
| import { Terminal, XtermTerminal, NodeJsProcess } from "../types"; | ||
| export declare const withXterm: (terminal: Terminal, xterm: XtermTerminal) => Terminal; | ||
| export declare const withNodeProcess: (terminal: Terminal, process: NodeJsProcess, exitOnCtrlC?: boolean) => Terminal; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const utils_1 = require("../utils"); | ||
| exports.withXterm = (terminal, xterm) => { | ||
| terminal.io.stdout.listen(data => xterm.write(data.replace(/\n/g, "\r\n") // xterm needs "\r" for line breaks | ||
| )); | ||
| xterm.on("key", (key, event) => terminal.io.keypress.emit({ | ||
| sequence: event.keyCode === 8 ? "\b" : key, | ||
| ctrl: event.ctrlKey, | ||
| shift: event.shiftKey, | ||
| meta: event.metaKey | ||
| })); | ||
| return terminal; | ||
| }; | ||
| exports.withNodeProcess = (terminal, process, exitOnCtrlC = true) => { | ||
| terminal.io.stdout.listen(utils_1.bindMethod(process.stdout, "write")); | ||
| process.stdin.on("keypress", (_, data) => { | ||
| if (exitOnCtrlC && data.ctrl && data.sequence == "\u0003") | ||
| process.exit(); | ||
| terminal.io.keypress.emit(data); | ||
| }); | ||
| return terminal; | ||
| }; |
| import { TerminalState, KeypressData } from "../types"; | ||
| export declare const r: { | ||
| typing: ({ text, input }: TerminalState, { sequence }: KeypressData) => TerminalState; | ||
| pipe: (...rs: ((state: TerminalState, key: KeypressData) => TerminalState)[]) => (state: TerminalState, key: KeypressData) => TerminalState; | ||
| }; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const typing_1 = require("./typing"); | ||
| exports.r = { | ||
| typing: typing_1.typing, | ||
| pipe: (...rs) => (state, key) => rs.reduce((s, r) => r(s, key), state) | ||
| }; |
| import { TerminalState, KeypressData } from "../types"; | ||
| export declare const typing: ({ text, input }: TerminalState, { sequence }: KeypressData) => TerminalState; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const utils_1 = require("../utils"); | ||
| const derivers_1 = require("../derivers/"); | ||
| exports.typing = ({ text, input }, { sequence }) => input === null | ||
| ? ({ text, input }) : | ||
| (({ key, isEscapeChar }) => ({ | ||
| text: !isEscapeChar | ||
| ? derivers_1.t.splice(text, derivers_1.i.currentPos(input), 0, sequence) : | ||
| key === "BACKSPACE" && input.caretOffset !== 0 | ||
| ? derivers_1.t.splice(text, derivers_1.i.currentPos(input), -1) : | ||
| key === "DELETE" && input.caretOffset !== input.length | ||
| ? derivers_1.t.splice(text, derivers_1.i.currentPos(input), 1) : | ||
| text, | ||
| input: { | ||
| position: input.position, | ||
| caretOffset: !isEscapeChar | ||
| ? input.caretOffset + 1 : | ||
| (key === "LEFT" || key === "BACKSPACE") && input.caretOffset !== 0 | ||
| ? input.caretOffset - 1 : | ||
| key === "RIGHT" && input.caretOffset !== input.length | ||
| ? input.caretOffset + 1 : | ||
| key === "END" | ||
| ? input.length : | ||
| key === "HOME" | ||
| ? 0 : | ||
| input.caretOffset, | ||
| length: !isEscapeChar | ||
| ? input.length + 1 : | ||
| ((key === "BACKSPACE" && input.caretOffset !== 0) || | ||
| (key === "DELETE" && input.caretOffset !== input.length)) | ||
| ? input.length - 1 : | ||
| input.length | ||
| } | ||
| }))({ | ||
| key: utils_1.toKeyname(sequence), | ||
| isEscapeChar: /[^a-zA-Z0-9 ]/.test(sequence) | ||
| }); |
| import { Terminal } from "./types"; | ||
| export declare const terminal: () => Terminal; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const utils_1 = require("./utils"); | ||
| const derivers_1 = require("./derivers"); | ||
| exports.terminal = () => { | ||
| let currentState = { | ||
| text: "", | ||
| input: null | ||
| }; | ||
| let prevState = currentState; | ||
| const listeners = { | ||
| keypress: [], | ||
| stdout: [], | ||
| state: [] | ||
| }; | ||
| const terminal = { | ||
| state: { | ||
| get: () => currentState, | ||
| set: state => { | ||
| prevState = currentState; | ||
| currentState = state; | ||
| utils_1.mergeFns(listeners.state)(currentState); | ||
| if (!areStateEqual(currentState, prevState)) { | ||
| utils_1.mergeFns(listeners.stdout)(toStdout(currentState)); | ||
| } | ||
| }, | ||
| reduce: reducer => terminal.state.set(reducer(currentState)), | ||
| listen: utils_1.bindMethod(listeners.state, "push") | ||
| }, | ||
| io: { | ||
| keypress: { | ||
| emit: data => listeners.keypress.forEach(listener => listener(data)), | ||
| listen: utils_1.bindMethod(listeners.keypress, "push") | ||
| }, | ||
| stdout: { | ||
| listen: utils_1.bindMethod(listeners.stdout, "push") | ||
| } | ||
| } | ||
| }; | ||
| return terminal; | ||
| }; | ||
| const toStdout = (state) => utils_1.ansiEscapes.cursorMove(0, 0) + | ||
| utils_1.ansiEscapes.clearScreen + | ||
| state.text + | ||
| (state.input | ||
| ? utils_1.ansiEscapes.cursorTo(...(({ x, y }) => [x, y])(derivers_1.i.currentPos(state.input))) | ||
| : ""); | ||
| const areStateEqual = (a, b) => a.text === b.text && (a.input === b.input || (a.input !== null && | ||
| b.input !== null && | ||
| a.input.position.x === b.input.position.x && | ||
| a.input.position.y === b.input.position.y && | ||
| a.input.caretOffset === b.input.caretOffset && | ||
| a.input.length === b.input.length)); |
| import { DeepReadonly } from "./utils"; | ||
| export declare type Terminal = { | ||
| state: { | ||
| get: () => DeepReadonly<TerminalState>; | ||
| set: (state: TerminalState) => void; | ||
| reduce: (reducer: (state: TerminalState) => TerminalState) => void; | ||
| listen: (listener: TerminalStateListener) => void; | ||
| }; | ||
| io: { | ||
| keypress: { | ||
| emit: (data: KeypressData) => void; | ||
| listen: (listener: KeypressListener) => void; | ||
| }; | ||
| stdout: { | ||
| listen: (listener: StdoutListener) => void; | ||
| }; | ||
| }; | ||
| }; | ||
| export declare type TerminalState = { | ||
| text: string; | ||
| input: null | { | ||
| position: { | ||
| x: number; | ||
| y: number; | ||
| }; | ||
| caretOffset: number; | ||
| length: number; | ||
| }; | ||
| }; | ||
| export declare type KeypressData = { | ||
| sequence: string; | ||
| ctrl: boolean; | ||
| shift: boolean; | ||
| meta: boolean; | ||
| }; | ||
| export declare type KeypressListener = (data: KeypressData) => void; | ||
| export declare type StdoutListener = (data: string) => void; | ||
| export declare type TerminalStateListener = (state: TerminalState) => void; | ||
| export declare type XtermTerminal = { | ||
| write: (data: string) => void; | ||
| on: (eventName: "key", listener: (key: string, event: KeyboardEvent) => void) => void; | ||
| }; | ||
| export declare type NodeJsProcess = { | ||
| stdout: { | ||
| write: (data: string) => void; | ||
| }; | ||
| stdin: { | ||
| on: (eventName: "keypress", listener: (key: string, extra: { | ||
| sequence: string; | ||
| ctrl: boolean; | ||
| shift: boolean; | ||
| meta: boolean; | ||
| }) => void) => void; | ||
| }; | ||
| exit: () => void; | ||
| }; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); |
| export declare const toKeyname: (sequence: string) => "LEFT" | "RIGHT" | "BACKSPACE" | "DELETE" | "HOME" | "END" | undefined; | ||
| export declare const ansiEscapes: { | ||
| cursorMove: (x: number, y: number) => string; | ||
| clearScreen: string; | ||
| cursorTo: (x: number, y: number) => string; | ||
| }; | ||
| export declare const bindMethod: <T extends object, P extends keyof T = keyof T>(stuff: T, method: { [K in P]: T[K] extends Function ? K : never; }[P]) => any; | ||
| export declare const mergeFns: <A extends any[]>(fns: ((...args: A) => any)[]) => (...args: A) => void; | ||
| export declare type DeepReadonly<T> = Readonly<{ | ||
| [K in keyof T]: Readonly<T[K]>; | ||
| }>; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.toKeyname = (sequence) => sequence === "\u001b[D" | ||
| ? "LEFT" : | ||
| sequence === "\u001b[C" | ||
| ? "RIGHT" : | ||
| sequence === "\b" || sequence === "\u007f" // \u007f for linux | ||
| ? "BACKSPACE" : | ||
| sequence === "\u001b[3~" | ||
| ? "DELETE" : | ||
| sequence === "\u001b[1~" || sequence === "\u001b[H" // \u001b[H for xterm.js | ||
| ? "HOME" : | ||
| sequence === "\u001b[4~" || sequence === "\u001b[F" // \u001b[F for xterm.js | ||
| ? "END" : | ||
| undefined; | ||
| exports.ansiEscapes = { | ||
| cursorMove: (x, y) => (x < 0 | ||
| ? "\u001B[" + (-x) + "D" | ||
| : "\u001B[" + x + "C") + | ||
| (y < 0 | ||
| ? "\u001B[" + (-y) + "A" | ||
| : "\u001B[" + y + "B"), | ||
| clearScreen: "\u001Bc", | ||
| cursorTo: (x, y) => "\u001B[" + (y + 1) + ";" + (x + 1) + "H" | ||
| }; | ||
| exports.bindMethod = (stuff, method) => stuff[method].bind(stuff); | ||
| exports.mergeFns = (fns) => (...args) => fns.forEach(fn => fn(...args)); |
+1
-1
| { | ||
| "name": "staerm", | ||
| "version": "3.0.4", | ||
| "version": "3.1.4", | ||
| "description": "Stateful, declarative & predictive library to build reactive terminal UIs", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
26681
85.56%43
86.96%684
100%