@effect/platform-node-shared 0.45.0 → 0.46.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.
|
@@ -7,92 +7,81 @@ exports.make = exports.layer = void 0;
|
|
|
7
7
|
var Error = _interopRequireWildcard(require("@effect/platform/Error"));
|
|
8
8
|
var Terminal = _interopRequireWildcard(require("@effect/platform/Terminal"));
|
|
9
9
|
var Effect = _interopRequireWildcard(require("effect/Effect"));
|
|
10
|
+
var Exit = _interopRequireWildcard(require("effect/Exit"));
|
|
10
11
|
var Layer = _interopRequireWildcard(require("effect/Layer"));
|
|
12
|
+
var Mailbox = _interopRequireWildcard(require("effect/Mailbox"));
|
|
11
13
|
var Option = _interopRequireWildcard(require("effect/Option"));
|
|
14
|
+
var RcRef = _interopRequireWildcard(require("effect/RcRef"));
|
|
12
15
|
var readline = _interopRequireWildcard(require("node:readline"));
|
|
13
16
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
14
17
|
const defaultShouldQuit = input => input.key.ctrl && (input.key.name === "c" || input.key.name === "d");
|
|
15
18
|
/** @internal */
|
|
16
|
-
const make =
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
// Acquire
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
rl.close();
|
|
19
|
+
const make = exports.make = /*#__PURE__*/Effect.fnUntraced(function* (shouldQuit = defaultShouldQuit) {
|
|
20
|
+
const stdin = process.stdin;
|
|
21
|
+
const stdout = process.stdout;
|
|
22
|
+
// Acquire readline interface with TTY setup/cleanup inside the scope
|
|
23
|
+
const rlRef = yield* RcRef.make({
|
|
24
|
+
acquire: Effect.acquireRelease(Effect.sync(() => {
|
|
25
|
+
const rl = readline.createInterface({
|
|
26
|
+
input: stdin,
|
|
27
|
+
escapeCodeTimeout: 50
|
|
28
|
+
});
|
|
29
|
+
readline.emitKeypressEvents(stdin, rl);
|
|
30
|
+
if (stdin.isTTY) {
|
|
31
|
+
stdin.setRawMode(true);
|
|
32
|
+
}
|
|
33
|
+
return rl;
|
|
34
|
+
}), rl => Effect.sync(() => {
|
|
35
|
+
if (stdin.isTTY) {
|
|
36
|
+
stdin.setRawMode(false);
|
|
37
|
+
}
|
|
38
|
+
rl.close();
|
|
39
|
+
}))
|
|
38
40
|
});
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
41
|
+
const columns = Effect.sync(() => stdout.columns ?? 0);
|
|
42
|
+
const readInput = Effect.gen(function* () {
|
|
43
|
+
yield* RcRef.get(rlRef);
|
|
44
|
+
const mailbox = yield* Mailbox.make();
|
|
45
|
+
const handleKeypress = (s, k) => {
|
|
42
46
|
const userInput = {
|
|
43
|
-
input: Option.fromNullable(
|
|
47
|
+
input: Option.fromNullable(s),
|
|
44
48
|
key: {
|
|
45
|
-
name:
|
|
46
|
-
ctrl:
|
|
47
|
-
meta:
|
|
48
|
-
shift:
|
|
49
|
+
name: k.name ?? "",
|
|
50
|
+
ctrl: !!k.ctrl,
|
|
51
|
+
meta: !!k.meta,
|
|
52
|
+
shift: !!k.shift
|
|
49
53
|
}
|
|
50
54
|
};
|
|
51
55
|
if (shouldQuit(userInput)) {
|
|
52
|
-
|
|
56
|
+
mailbox.unsafeDone(Exit.void);
|
|
53
57
|
} else {
|
|
54
|
-
|
|
58
|
+
mailbox.unsafeOffer(userInput);
|
|
55
59
|
}
|
|
56
60
|
};
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
});
|
|
61
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => stdin.off("keypress", handleKeypress)));
|
|
62
|
+
stdin.on("keypress", handleKeypress);
|
|
63
|
+
return mailbox;
|
|
61
64
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
rl.on("line", handleLine);
|
|
68
|
-
return Effect.sync(() => {
|
|
69
|
-
rl.removeListener("line", handleLine);
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
const readInput = Effect.acquireUseRelease(acquireReadlineInterface.pipe(Effect.map(emitKeypressEvents)), () => handleKeypressEvent(input), releaseReadlineInterface);
|
|
73
|
-
const readLine = Effect.acquireUseRelease(acquireReadlineInterface, rl => handleLineEvent(rl), releaseReadlineInterface);
|
|
65
|
+
const readLine = RcRef.get(rlRef).pipe(Effect.flatMap(readlineInterface => Effect.async(resume => {
|
|
66
|
+
const onLine = line => resume(Effect.succeed(line));
|
|
67
|
+
readlineInterface.once("line", onLine);
|
|
68
|
+
return Effect.sync(() => readlineInterface.off("line", onLine));
|
|
69
|
+
})), Effect.scoped);
|
|
74
70
|
const display = prompt => Effect.uninterruptible(Effect.async(resume => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
cause: err
|
|
82
|
-
})));
|
|
83
|
-
}
|
|
84
|
-
resume(Effect.void);
|
|
85
|
-
});
|
|
71
|
+
stdout.write(prompt, err => err ? resume(Effect.fail(new Error.BadArgument({
|
|
72
|
+
module: "Terminal",
|
|
73
|
+
method: "display",
|
|
74
|
+
description: "Failed to write prompt to stdout",
|
|
75
|
+
cause: err
|
|
76
|
+
}))) : resume(Effect.void));
|
|
86
77
|
}));
|
|
87
78
|
return Terminal.Terminal.of({
|
|
88
|
-
|
|
89
|
-
columns: Effect.sync(() => output.columns || 0),
|
|
79
|
+
columns,
|
|
90
80
|
readInput,
|
|
91
81
|
readLine,
|
|
92
82
|
display
|
|
93
83
|
});
|
|
94
84
|
});
|
|
95
85
|
/** @internal */
|
|
96
|
-
exports.make = make;
|
|
97
86
|
const layer = exports.layer = /*#__PURE__*/Layer.scoped(Terminal.Terminal, /*#__PURE__*/make(defaultShouldQuit));
|
|
98
87
|
//# sourceMappingURL=terminal.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.js","names":["Error","_interopRequireWildcard","require","Terminal","Effect","Layer","Option","readline","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","defaultShouldQuit","input","key","ctrl","name","make","
|
|
1
|
+
{"version":3,"file":"terminal.js","names":["Error","_interopRequireWildcard","require","Terminal","Effect","Exit","Layer","Mailbox","Option","RcRef","readline","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","defaultShouldQuit","input","key","ctrl","name","make","exports","fnUntraced","shouldQuit","stdin","process","stdout","rlRef","acquire","acquireRelease","sync","rl","createInterface","escapeCodeTimeout","emitKeypressEvents","isTTY","setRawMode","close","columns","readInput","gen","mailbox","handleKeypress","s","k","userInput","fromNullable","meta","shift","unsafeDone","void","unsafeOffer","addFinalizer","off","on","readLine","pipe","flatMap","readlineInterface","async","resume","onLine","line","succeed","once","scoped","display","prompt","uninterruptible","write","err","fail","BadArgument","module","method","description","cause","of","layer"],"sources":["../../../src/internal/terminal.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
|
@@ -1,85 +1,75 @@
|
|
|
1
1
|
import * as Error from "@effect/platform/Error";
|
|
2
2
|
import * as Terminal from "@effect/platform/Terminal";
|
|
3
3
|
import * as Effect from "effect/Effect";
|
|
4
|
+
import * as Exit from "effect/Exit";
|
|
4
5
|
import * as Layer from "effect/Layer";
|
|
6
|
+
import * as Mailbox from "effect/Mailbox";
|
|
5
7
|
import * as Option from "effect/Option";
|
|
8
|
+
import * as RcRef from "effect/RcRef";
|
|
6
9
|
import * as readline from "node:readline";
|
|
7
10
|
const defaultShouldQuit = input => input.key.ctrl && (input.key.name === "c" || input.key.name === "d");
|
|
8
11
|
/** @internal */
|
|
9
|
-
export const make =
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
// Acquire
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
rl.close();
|
|
12
|
+
export const make = /*#__PURE__*/Effect.fnUntraced(function* (shouldQuit = defaultShouldQuit) {
|
|
13
|
+
const stdin = process.stdin;
|
|
14
|
+
const stdout = process.stdout;
|
|
15
|
+
// Acquire readline interface with TTY setup/cleanup inside the scope
|
|
16
|
+
const rlRef = yield* RcRef.make({
|
|
17
|
+
acquire: Effect.acquireRelease(Effect.sync(() => {
|
|
18
|
+
const rl = readline.createInterface({
|
|
19
|
+
input: stdin,
|
|
20
|
+
escapeCodeTimeout: 50
|
|
21
|
+
});
|
|
22
|
+
readline.emitKeypressEvents(stdin, rl);
|
|
23
|
+
if (stdin.isTTY) {
|
|
24
|
+
stdin.setRawMode(true);
|
|
25
|
+
}
|
|
26
|
+
return rl;
|
|
27
|
+
}), rl => Effect.sync(() => {
|
|
28
|
+
if (stdin.isTTY) {
|
|
29
|
+
stdin.setRawMode(false);
|
|
30
|
+
}
|
|
31
|
+
rl.close();
|
|
32
|
+
}))
|
|
31
33
|
});
|
|
32
|
-
|
|
33
|
-
const
|
|
34
|
-
|
|
34
|
+
const columns = Effect.sync(() => stdout.columns ?? 0);
|
|
35
|
+
const readInput = Effect.gen(function* () {
|
|
36
|
+
yield* RcRef.get(rlRef);
|
|
37
|
+
const mailbox = yield* Mailbox.make();
|
|
38
|
+
const handleKeypress = (s, k) => {
|
|
35
39
|
const userInput = {
|
|
36
|
-
input: Option.fromNullable(
|
|
40
|
+
input: Option.fromNullable(s),
|
|
37
41
|
key: {
|
|
38
|
-
name:
|
|
39
|
-
ctrl:
|
|
40
|
-
meta:
|
|
41
|
-
shift:
|
|
42
|
+
name: k.name ?? "",
|
|
43
|
+
ctrl: !!k.ctrl,
|
|
44
|
+
meta: !!k.meta,
|
|
45
|
+
shift: !!k.shift
|
|
42
46
|
}
|
|
43
47
|
};
|
|
44
48
|
if (shouldQuit(userInput)) {
|
|
45
|
-
|
|
49
|
+
mailbox.unsafeDone(Exit.void);
|
|
46
50
|
} else {
|
|
47
|
-
|
|
51
|
+
mailbox.unsafeOffer(userInput);
|
|
48
52
|
}
|
|
49
53
|
};
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
});
|
|
54
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => stdin.off("keypress", handleKeypress)));
|
|
55
|
+
stdin.on("keypress", handleKeypress);
|
|
56
|
+
return mailbox;
|
|
54
57
|
});
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
rl.on("line", handleLine);
|
|
61
|
-
return Effect.sync(() => {
|
|
62
|
-
rl.removeListener("line", handleLine);
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
const readInput = Effect.acquireUseRelease(acquireReadlineInterface.pipe(Effect.map(emitKeypressEvents)), () => handleKeypressEvent(input), releaseReadlineInterface);
|
|
66
|
-
const readLine = Effect.acquireUseRelease(acquireReadlineInterface, rl => handleLineEvent(rl), releaseReadlineInterface);
|
|
58
|
+
const readLine = RcRef.get(rlRef).pipe(Effect.flatMap(readlineInterface => Effect.async(resume => {
|
|
59
|
+
const onLine = line => resume(Effect.succeed(line));
|
|
60
|
+
readlineInterface.once("line", onLine);
|
|
61
|
+
return Effect.sync(() => readlineInterface.off("line", onLine));
|
|
62
|
+
})), Effect.scoped);
|
|
67
63
|
const display = prompt => Effect.uninterruptible(Effect.async(resume => {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
cause: err
|
|
75
|
-
})));
|
|
76
|
-
}
|
|
77
|
-
resume(Effect.void);
|
|
78
|
-
});
|
|
64
|
+
stdout.write(prompt, err => err ? resume(Effect.fail(new Error.BadArgument({
|
|
65
|
+
module: "Terminal",
|
|
66
|
+
method: "display",
|
|
67
|
+
description: "Failed to write prompt to stdout",
|
|
68
|
+
cause: err
|
|
69
|
+
}))) : resume(Effect.void));
|
|
79
70
|
}));
|
|
80
71
|
return Terminal.Terminal.of({
|
|
81
|
-
|
|
82
|
-
columns: Effect.sync(() => output.columns || 0),
|
|
72
|
+
columns,
|
|
83
73
|
readInput,
|
|
84
74
|
readLine,
|
|
85
75
|
display
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.js","names":["Error","Terminal","Effect","Layer","Option","readline","defaultShouldQuit","input","key","ctrl","name","make","shouldQuit","
|
|
1
|
+
{"version":3,"file":"terminal.js","names":["Error","Terminal","Effect","Exit","Layer","Mailbox","Option","RcRef","readline","defaultShouldQuit","input","key","ctrl","name","make","fnUntraced","shouldQuit","stdin","process","stdout","rlRef","acquire","acquireRelease","sync","rl","createInterface","escapeCodeTimeout","emitKeypressEvents","isTTY","setRawMode","close","columns","readInput","gen","get","mailbox","handleKeypress","s","k","userInput","fromNullable","meta","shift","unsafeDone","void","unsafeOffer","addFinalizer","off","on","readLine","pipe","flatMap","readlineInterface","async","resume","onLine","line","succeed","once","scoped","display","prompt","uninterruptible","write","err","fail","BadArgument","module","method","description","cause","of","layer"],"sources":["../../../src/internal/terminal.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@effect/platform-node-shared",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "Unified interfaces for common platform-specific services",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
"ws": "^8.18.2"
|
|
17
17
|
},
|
|
18
18
|
"peerDependencies": {
|
|
19
|
-
"@effect/cluster": "^0.
|
|
20
|
-
"@effect/platform": "^0.
|
|
21
|
-
"@effect/rpc": "^0.
|
|
22
|
-
"@effect/sql": "^0.
|
|
19
|
+
"@effect/cluster": "^0.45.0",
|
|
20
|
+
"@effect/platform": "^0.90.0",
|
|
21
|
+
"@effect/rpc": "^0.67.0",
|
|
22
|
+
"@effect/sql": "^0.44.0",
|
|
23
23
|
"effect": "^3.17.0"
|
|
24
24
|
},
|
|
25
25
|
"publishConfig": {
|
package/src/internal/terminal.ts
CHANGED
|
@@ -1,126 +1,101 @@
|
|
|
1
1
|
import * as Error from "@effect/platform/Error"
|
|
2
2
|
import * as Terminal from "@effect/platform/Terminal"
|
|
3
3
|
import * as Effect from "effect/Effect"
|
|
4
|
+
import * as Exit from "effect/Exit"
|
|
4
5
|
import * as Layer from "effect/Layer"
|
|
6
|
+
import * as Mailbox from "effect/Mailbox"
|
|
5
7
|
import * as Option from "effect/Option"
|
|
8
|
+
import * as RcRef from "effect/RcRef"
|
|
6
9
|
import * as readline from "node:readline"
|
|
7
10
|
|
|
8
|
-
const defaultShouldQuit = (input: Terminal.UserInput)
|
|
11
|
+
const defaultShouldQuit = (input: Terminal.UserInput) =>
|
|
9
12
|
input.key.ctrl && (input.key.name === "c" || input.key.name === "d")
|
|
10
13
|
|
|
11
14
|
/** @internal */
|
|
12
|
-
export const make = (
|
|
15
|
+
export const make = Effect.fnUntraced(function*(
|
|
13
16
|
shouldQuit: (input: Terminal.UserInput) => boolean = defaultShouldQuit
|
|
14
|
-
)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const output = yield* Effect.sync(() => globalThis.process.stdout)
|
|
17
|
+
) {
|
|
18
|
+
const stdin = process.stdin
|
|
19
|
+
const stdout = process.stdout
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
escapeCodeTimeout: 50
|
|
24
|
-
|
|
21
|
+
// Acquire readline interface with TTY setup/cleanup inside the scope
|
|
22
|
+
const rlRef = yield* RcRef.make({
|
|
23
|
+
acquire: Effect.acquireRelease(
|
|
24
|
+
Effect.sync(() => {
|
|
25
|
+
const rl = readline.createInterface({ input: stdin, escapeCodeTimeout: 50 })
|
|
26
|
+
readline.emitKeypressEvents(stdin, rl)
|
|
27
|
+
|
|
28
|
+
if (stdin.isTTY) {
|
|
29
|
+
stdin.setRawMode(true)
|
|
30
|
+
}
|
|
31
|
+
return rl
|
|
32
|
+
}),
|
|
33
|
+
(rl) =>
|
|
34
|
+
Effect.sync(() => {
|
|
35
|
+
if (stdin.isTTY) {
|
|
36
|
+
stdin.setRawMode(false)
|
|
37
|
+
}
|
|
38
|
+
rl.close()
|
|
39
|
+
})
|
|
25
40
|
)
|
|
41
|
+
})
|
|
26
42
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
43
|
+
const columns = Effect.sync(() => stdout.columns ?? 0)
|
|
44
|
+
|
|
45
|
+
const readInput = Effect.gen(function*() {
|
|
46
|
+
yield* RcRef.get(rlRef)
|
|
47
|
+
const mailbox = yield* Mailbox.make<Terminal.UserInput>()
|
|
48
|
+
const handleKeypress = (s: string | undefined, k: readline.Key) => {
|
|
49
|
+
const userInput = {
|
|
50
|
+
input: Option.fromNullable(s),
|
|
51
|
+
key: { name: k.name ?? "", ctrl: !!k.ctrl, meta: !!k.meta, shift: !!k.shift }
|
|
52
|
+
}
|
|
53
|
+
if (shouldQuit(userInput)) {
|
|
54
|
+
mailbox.unsafeDone(Exit.void)
|
|
55
|
+
} else {
|
|
56
|
+
mailbox.unsafeOffer(userInput)
|
|
32
57
|
}
|
|
33
|
-
return rl
|
|
34
58
|
}
|
|
59
|
+
yield* Effect.addFinalizer(() => Effect.sync(() => stdin.off("keypress", handleKeypress)))
|
|
60
|
+
stdin.on("keypress", handleKeypress)
|
|
61
|
+
return mailbox as Mailbox.ReadonlyMailbox<Terminal.UserInput>
|
|
62
|
+
})
|
|
35
63
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
Effect.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
rl.close()
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
// Handle the `"keypress"` event emitted by `stdin` (forced by readline)
|
|
46
|
-
const handleKeypressEvent = (input: typeof globalThis.process.stdin) =>
|
|
47
|
-
Effect.async<Terminal.UserInput, Terminal.QuitException>((resume) => {
|
|
48
|
-
const handleKeypress = (input: string | undefined, key: readline.Key) => {
|
|
49
|
-
const userInput: Terminal.UserInput = {
|
|
50
|
-
input: Option.fromNullable(input),
|
|
51
|
-
key: {
|
|
52
|
-
name: key.name || "",
|
|
53
|
-
ctrl: key.ctrl || false,
|
|
54
|
-
meta: key.meta || false,
|
|
55
|
-
shift: key.shift || false
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
if (shouldQuit(userInput)) {
|
|
59
|
-
resume(Effect.fail(new Terminal.QuitException()))
|
|
60
|
-
} else {
|
|
61
|
-
resume(Effect.succeed(userInput))
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
input.once("keypress", handleKeypress)
|
|
65
|
-
return Effect.sync(() => {
|
|
66
|
-
input.removeListener("keypress", handleKeypress)
|
|
67
|
-
})
|
|
64
|
+
const readLine = RcRef.get(rlRef).pipe(
|
|
65
|
+
Effect.flatMap((readlineInterface) =>
|
|
66
|
+
Effect.async<string, Terminal.QuitException>((resume) => {
|
|
67
|
+
const onLine = (line: string) => resume(Effect.succeed(line))
|
|
68
|
+
readlineInterface.once("line", onLine)
|
|
69
|
+
return Effect.sync(() => readlineInterface.off("line", onLine))
|
|
68
70
|
})
|
|
71
|
+
),
|
|
72
|
+
Effect.scoped
|
|
73
|
+
)
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
Effect.async<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
const display = (prompt: string) =>
|
|
76
|
+
Effect.uninterruptible(
|
|
77
|
+
Effect.async<void, Error.PlatformError>((resume) => {
|
|
78
|
+
stdout.write(prompt, (err) =>
|
|
79
|
+
err
|
|
80
|
+
? resume(Effect.fail(
|
|
81
|
+
new Error.BadArgument({
|
|
82
|
+
module: "Terminal",
|
|
83
|
+
method: "display",
|
|
84
|
+
description: "Failed to write prompt to stdout",
|
|
85
|
+
cause: err
|
|
86
|
+
})
|
|
87
|
+
))
|
|
88
|
+
: resume(Effect.void))
|
|
80
89
|
})
|
|
81
|
-
|
|
82
|
-
const readInput = Effect.acquireUseRelease(
|
|
83
|
-
acquireReadlineInterface.pipe(Effect.map(emitKeypressEvents)),
|
|
84
|
-
() => handleKeypressEvent(input),
|
|
85
|
-
releaseReadlineInterface
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
const readLine = Effect.acquireUseRelease(
|
|
89
|
-
acquireReadlineInterface,
|
|
90
|
-
(rl) => handleLineEvent(rl),
|
|
91
|
-
releaseReadlineInterface
|
|
92
90
|
)
|
|
93
91
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
resume(Effect.fail(
|
|
100
|
-
new Error.BadArgument({
|
|
101
|
-
module: "Terminal",
|
|
102
|
-
method: "display",
|
|
103
|
-
description: "Failed to write prompt to output",
|
|
104
|
-
cause: err
|
|
105
|
-
})
|
|
106
|
-
))
|
|
107
|
-
}
|
|
108
|
-
resume(Effect.void)
|
|
109
|
-
})
|
|
110
|
-
})
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
return Terminal.Terminal.of({
|
|
114
|
-
// The columns property can be undefined if stdout was redirected
|
|
115
|
-
columns: Effect.sync(() => output.columns || 0),
|
|
116
|
-
readInput,
|
|
117
|
-
readLine,
|
|
118
|
-
display
|
|
119
|
-
})
|
|
92
|
+
return Terminal.Terminal.of({
|
|
93
|
+
columns,
|
|
94
|
+
readInput,
|
|
95
|
+
readLine,
|
|
96
|
+
display
|
|
120
97
|
})
|
|
98
|
+
})
|
|
121
99
|
|
|
122
100
|
/** @internal */
|
|
123
|
-
export const layer: Layer.Layer<Terminal.Terminal> = Layer.scoped(
|
|
124
|
-
Terminal.Terminal,
|
|
125
|
-
make(defaultShouldQuit)
|
|
126
|
-
)
|
|
101
|
+
export const layer: Layer.Layer<Terminal.Terminal> = Layer.scoped(Terminal.Terminal, make(defaultShouldQuit))
|