47 lines
2.9 KiB
Markdown
47 lines
2.9 KiB
Markdown
Implement the `sl` ("steam locomotive") command from Linux in TypeScript. I want an __exact replica__ of the original Linux command. Strictly follow the following APIs and concepts:
|
|
1. class SimpleStream<T>
|
|
- on(listener: (data: T) => any): void
|
|
- Attaches a listener to the stream
|
|
- param listener -> the function to call when data is streamed
|
|
- once(listener: (data: T) => any): void
|
|
- Attaches a one-time listener to the stream
|
|
- param listener -> the function to call when data is streamed
|
|
- wait(): Promise<T>
|
|
- Patiently waits until new data is streamed, then returns it
|
|
- return a promise for a single chunk of streamed data
|
|
- off(listener: Function): void
|
|
- Removes a listener from the stream
|
|
- param listener -> the function to remove
|
|
- emit(data: T): void
|
|
- Streams data
|
|
- param data -> the data to stream
|
|
2. Escape codes
|
|
- Escape codes can be formatted using one of the following syntaxes:
|
|
- `\{code letter}` -> for short codes like \n or \f
|
|
- `\0{code id};{first parameter};{second parameter};{...parameters}\0` -> for longer codes with complex parameters like cursor movement codes
|
|
- A semicolon right after or before a null terminator (`\0`) inside of an escape code is a syntax error
|
|
- Supported escape codes:
|
|
- Short codes (<code letter> -> <description>)
|
|
1. n -> line feed (new line)
|
|
2. f -> form feed (new page)
|
|
- Longer codes (<code id>,<first parameter>,<...parameters> -> <description>)
|
|
1. cmr,{delta x},{delta y} -> moves the cursor relative to its current position by the specified amounts
|
|
2. cma,{absolute x},{absolute y} -> moves the cursor absolute in the terminal coordinate space
|
|
- Example usage:
|
|
- `stdout.emit("\\cma;3;2\\")` - sets the cursor position to the specified XY coordinates - x=3, y=2
|
|
2. stdout/stdin - SimpleStream instances
|
|
- they function as input/output interfaces to send text between the shell and other programs
|
|
- stdout allows for formatting using the above mentioned Escape codes
|
|
- Example usage:
|
|
- `stdout.emit("Hello world!\n")` - streams the text to the stdout stream, works like printf in C
|
|
- ```stdin.once(data => stdout.emit(`Received data: ${data}`))``` - creates a single use listener in the stdin stream and prints out the received data
|
|
3. abstract class Program
|
|
- abstract Exec(stdin: SimpleStream<string>, stdout: SimpleStream<string>, workdir: Item, args: string[]): Promise<number>
|
|
- Entry point for a program
|
|
- param stdin -> input stream
|
|
- param stdout -> output stream
|
|
- param workdir -> Working directory filesystem item
|
|
- param args -> arguments array, including the executed program name from the shell
|
|
- for example for echo command: `[ "echo", "test", "one", "two", "three" ]`
|
|
- returns a posix-like exit code
|