@effectionx/process 0.5.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/README.md +12 -0
- package/esm/mod.d.ts +3 -0
- package/esm/mod.d.ts.map +1 -0
- package/esm/mod.js +2 -0
- package/esm/package.json +3 -0
- package/esm/src/daemon.d.ts +11 -0
- package/esm/src/daemon.d.ts.map +1 -0
- package/esm/src/daemon.js +20 -0
- package/esm/src/eventemitter.d.ts +22 -0
- package/esm/src/eventemitter.d.ts.map +1 -0
- package/esm/src/eventemitter.js +40 -0
- package/esm/src/exec/api.d.ts +70 -0
- package/esm/src/exec/api.d.ts.map +1 -0
- package/esm/src/exec/api.js +1 -0
- package/esm/src/exec/error.d.ts +14 -0
- package/esm/src/exec/error.d.ts.map +1 -0
- package/esm/src/exec/error.js +54 -0
- package/esm/src/exec/posix.d.ts +3 -0
- package/esm/src/exec/posix.d.ts.map +1 -0
- package/esm/src/exec/posix.js +110 -0
- package/esm/src/exec/win32.d.ts +4 -0
- package/esm/src/exec/win32.d.ts.map +1 -0
- package/esm/src/exec/win32.js +173 -0
- package/esm/src/exec.d.ts +16 -0
- package/esm/src/exec.d.ts.map +1 -0
- package/esm/src/exec.js +75 -0
- package/esm/src/helpers.d.ts +12 -0
- package/esm/src/helpers.d.ts.map +1 -0
- package/esm/src/helpers.js +71 -0
- package/package.json +34 -0
- package/script/mod.d.ts +3 -0
- package/script/mod.d.ts.map +1 -0
- package/script/mod.js +20 -0
- package/script/package.json +3 -0
- package/script/src/daemon.d.ts +11 -0
- package/script/src/daemon.d.ts.map +1 -0
- package/script/src/daemon.js +23 -0
- package/script/src/eventemitter.d.ts +22 -0
- package/script/src/eventemitter.d.ts.map +1 -0
- package/script/src/eventemitter.js +44 -0
- package/script/src/exec/api.d.ts +70 -0
- package/script/src/exec/api.d.ts.map +1 -0
- package/script/src/exec/api.js +2 -0
- package/script/src/exec/error.d.ts +14 -0
- package/script/src/exec/error.d.ts.map +1 -0
- package/script/src/exec/error.js +59 -0
- package/script/src/exec/posix.d.ts +3 -0
- package/script/src/exec/posix.d.ts.map +1 -0
- package/script/src/exec/posix.js +117 -0
- package/script/src/exec/win32.d.ts +4 -0
- package/script/src/exec/win32.d.ts.map +1 -0
- package/script/src/exec/win32.js +178 -0
- package/script/src/exec.d.ts +16 -0
- package/script/src/exec.d.ts.map +1 -0
- package/script/src/exec.js +92 -0
- package/script/src/helpers.d.ts +12 -0
- package/script/src/helpers.d.ts.map +1 -0
- package/script/src/helpers.js +76 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isWin32 = exports.createWin32Process = void 0;
|
|
4
|
+
const node_os_1 = require("node:os");
|
|
5
|
+
const effection_1 = require("effection");
|
|
6
|
+
// @ts-types="npm:@types/cross-spawn@6.0.6"
|
|
7
|
+
const cross_spawn_1 = require("cross-spawn");
|
|
8
|
+
const ctrlc_windows_1 = require("ctrlc-windows");
|
|
9
|
+
const eventemitter_js_1 = require("../eventemitter.js");
|
|
10
|
+
const helpers_js_1 = require("../helpers.js");
|
|
11
|
+
const error_js_1 = require("./error.js");
|
|
12
|
+
function* killTree(pid) {
|
|
13
|
+
try {
|
|
14
|
+
const killer = (0, cross_spawn_1.spawn)("cmd.exe", ["/c", "taskkill", "/PID", String(pid), "/T", "/F"], { windowsHide: true, stdio: "ignore" });
|
|
15
|
+
yield* (0, eventemitter_js_1.once)(killer, "close");
|
|
16
|
+
}
|
|
17
|
+
catch (_) {
|
|
18
|
+
// best-effort; ignore errors
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const createWin32Process = function* createWin32Process(command, options) {
|
|
22
|
+
let processResult = (0, effection_1.withResolvers)();
|
|
23
|
+
// Windows-specific process spawning with different options than POSIX
|
|
24
|
+
let childProcess = (0, cross_spawn_1.spawn)(command, options.arguments || [], {
|
|
25
|
+
// We lose exit information and events if this is detached in windows
|
|
26
|
+
// and it opens a window in windows+powershell.
|
|
27
|
+
detached: false,
|
|
28
|
+
// The `shell` option is passed to `cross-spawn` to control whether a shell is used.
|
|
29
|
+
// On Windows, `shell: true` is necessary to run command strings, as it uses
|
|
30
|
+
// `cmd.exe` to parse the command and find executables in the PATH.
|
|
31
|
+
// Using a boolean `true` was previously disabled, causing ENOENT errors for
|
|
32
|
+
// commands that were not a direct path to an executable.
|
|
33
|
+
shell: options.shell || false,
|
|
34
|
+
// With stdio as pipe, windows gets stuck where neither the child nor the
|
|
35
|
+
// parent wants to close the stream, so we call it ourselves in the exit event.
|
|
36
|
+
stdio: "pipe",
|
|
37
|
+
// Hide the child window so that killing it will not block the parent
|
|
38
|
+
// with a Terminate Batch Process (Y/n)
|
|
39
|
+
windowsHide: true,
|
|
40
|
+
env: options.env,
|
|
41
|
+
cwd: options.cwd,
|
|
42
|
+
});
|
|
43
|
+
let { pid } = childProcess;
|
|
44
|
+
let io = {
|
|
45
|
+
stdout: yield* (0, helpers_js_1.useReadable)(childProcess.stdout),
|
|
46
|
+
stderr: yield* (0, helpers_js_1.useReadable)(childProcess.stderr),
|
|
47
|
+
stdoutDone: (0, effection_1.withResolvers)(),
|
|
48
|
+
stderrDone: (0, effection_1.withResolvers)(),
|
|
49
|
+
};
|
|
50
|
+
const stdout = (0, effection_1.createSignal)();
|
|
51
|
+
const stderr = (0, effection_1.createSignal)();
|
|
52
|
+
yield* (0, effection_1.spawn)(function* () {
|
|
53
|
+
let next = yield* io.stdout.next();
|
|
54
|
+
while (!next.done) {
|
|
55
|
+
stdout.send(next.value);
|
|
56
|
+
next = yield* io.stdout.next();
|
|
57
|
+
}
|
|
58
|
+
stdout.close();
|
|
59
|
+
io.stdoutDone.resolve();
|
|
60
|
+
});
|
|
61
|
+
yield* (0, effection_1.spawn)(function* () {
|
|
62
|
+
let next = yield* io.stderr.next();
|
|
63
|
+
while (!next.done) {
|
|
64
|
+
stderr.send(next.value);
|
|
65
|
+
next = yield* io.stderr.next();
|
|
66
|
+
}
|
|
67
|
+
stderr.close();
|
|
68
|
+
io.stderrDone.resolve();
|
|
69
|
+
});
|
|
70
|
+
yield* (0, effection_1.spawn)(function* trapError() {
|
|
71
|
+
const [error] = yield* (0, eventemitter_js_1.once)(childProcess, "error");
|
|
72
|
+
processResult.resolve((0, effection_1.Err)(error));
|
|
73
|
+
});
|
|
74
|
+
let stdin = {
|
|
75
|
+
send(data) {
|
|
76
|
+
childProcess.stdin.write(data);
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
yield* (0, effection_1.spawn)(function* () {
|
|
80
|
+
try {
|
|
81
|
+
let value = yield* (0, eventemitter_js_1.once)(childProcess, "close");
|
|
82
|
+
yield* (0, effection_1.all)([io.stdoutDone.operation, io.stderrDone.operation]);
|
|
83
|
+
processResult.resolve((0, effection_1.Ok)(value));
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
try {
|
|
87
|
+
// Only try to kill the process if it hasn't exited yet
|
|
88
|
+
if (childProcess.exitCode === null &&
|
|
89
|
+
childProcess.signalCode === null) {
|
|
90
|
+
if (typeof childProcess.pid === "undefined") {
|
|
91
|
+
// deno-lint-ignore no-unsafe-finally
|
|
92
|
+
throw new Error("no pid for childProcess");
|
|
93
|
+
}
|
|
94
|
+
let stdinStream = childProcess.stdin;
|
|
95
|
+
// Try graceful shutdown with ctrlc
|
|
96
|
+
try {
|
|
97
|
+
(0, ctrlc_windows_1.ctrlc)(childProcess.pid);
|
|
98
|
+
if (stdinStream.writable) {
|
|
99
|
+
try {
|
|
100
|
+
// Terminate batch process (Y/N)
|
|
101
|
+
stdinStream.write("Y\n");
|
|
102
|
+
}
|
|
103
|
+
catch (_err) {
|
|
104
|
+
// not much we can do here
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (_err) {
|
|
109
|
+
// ctrlc might fail
|
|
110
|
+
}
|
|
111
|
+
// Close stdin to allow process to exit cleanly
|
|
112
|
+
try {
|
|
113
|
+
stdinStream.end();
|
|
114
|
+
}
|
|
115
|
+
catch (_err) {
|
|
116
|
+
// stdin might already be closed
|
|
117
|
+
}
|
|
118
|
+
// Wait for graceful exit with a timeout
|
|
119
|
+
yield* (0, effection_1.race)([processResult.operation, (0, effection_1.sleep)(300)]);
|
|
120
|
+
// If process still hasn't exited, escalate
|
|
121
|
+
if (childProcess.exitCode === null &&
|
|
122
|
+
childProcess.signalCode === null) {
|
|
123
|
+
// Try regular kill first
|
|
124
|
+
try {
|
|
125
|
+
childProcess.kill();
|
|
126
|
+
}
|
|
127
|
+
catch (_err) {
|
|
128
|
+
// process might already be dead
|
|
129
|
+
}
|
|
130
|
+
// If still alive after kill, force-kill entire process tree
|
|
131
|
+
// This is necessary for bash on Windows where ctrlc doesn't work
|
|
132
|
+
// and child.kill() only kills the shell, leaving grandchildren alive
|
|
133
|
+
if (childProcess.exitCode === null &&
|
|
134
|
+
childProcess.signalCode === null) {
|
|
135
|
+
yield* killTree(childProcess.pid);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Wait for streams to finish
|
|
139
|
+
yield* (0, effection_1.all)([io.stdoutDone.operation, io.stderrDone.operation]);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
catch (_e) {
|
|
143
|
+
// do nothing, process is probably already dead
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
function* join() {
|
|
148
|
+
let result = yield* processResult.operation;
|
|
149
|
+
if (result.ok) {
|
|
150
|
+
let [code, signal] = result.value;
|
|
151
|
+
return { command, options, code, signal };
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
throw result.error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function* expect() {
|
|
158
|
+
let status = yield* join();
|
|
159
|
+
if (status.code != 0) {
|
|
160
|
+
throw new error_js_1.ExecError(status, command, options);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
return status;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// FYI: this function starts a process and returns without blocking
|
|
167
|
+
return {
|
|
168
|
+
pid: pid,
|
|
169
|
+
stdin,
|
|
170
|
+
stdout,
|
|
171
|
+
stderr,
|
|
172
|
+
join,
|
|
173
|
+
expect,
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
exports.createWin32Process = createWin32Process;
|
|
177
|
+
const isWin32 = () => (0, node_os_1.platform)() === "win32";
|
|
178
|
+
exports.isWin32 = isWin32;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Operation } from "effection";
|
|
2
|
+
import type { ExecOptions, Process, ProcessResult } from "./exec/api.js";
|
|
3
|
+
export * from "./exec/api.js";
|
|
4
|
+
export * from "./exec/error.js";
|
|
5
|
+
export interface Exec extends Operation<Process> {
|
|
6
|
+
join(): Operation<ProcessResult>;
|
|
7
|
+
expect(): Operation<ProcessResult>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Execute `command` with `options`. You should use this operation for processes
|
|
11
|
+
* that have a finite lifetime and on which you may wish to synchronize on the
|
|
12
|
+
* exit status. If you want to start a process like a server that spins up and runs
|
|
13
|
+
* forever, consider using `daemon()`
|
|
14
|
+
*/
|
|
15
|
+
export declare function exec(command: string, options?: ExecOptions): Exec;
|
|
16
|
+
//# sourceMappingURL=exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.d.ts","sourceRoot":"","sources":["../../src/src/exec.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAS,MAAM,WAAW,CAAC;AAClD,OAAO,KAAK,EAEV,WAAW,EAEX,OAAO,EACP,aAAa,EACd,MAAM,eAAe,CAAC;AAIvB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAEhC,MAAM,WAAW,IAAK,SAAQ,SAAS,CAAC,OAAO,CAAC;IAC9C,IAAI,IAAI,SAAS,CAAC,aAAa,CAAC,CAAC;IACjC,MAAM,IAAI,SAAS,CAAC,aAAa,CAAC,CAAC;CACpC;AAUD;;;;;GAKG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,IAAI,CAiErE"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.exec = exec;
|
|
18
|
+
const shellwords_1 = require("shellwords");
|
|
19
|
+
const effection_1 = require("effection");
|
|
20
|
+
const posix_js_1 = require("./exec/posix.js");
|
|
21
|
+
const win32_js_1 = require("./exec/win32.js");
|
|
22
|
+
__exportStar(require("./exec/api.js"), exports);
|
|
23
|
+
__exportStar(require("./exec/error.js"), exports);
|
|
24
|
+
const createProcess = (cmd, opts) => {
|
|
25
|
+
if ((0, win32_js_1.isWin32)()) {
|
|
26
|
+
return (0, win32_js_1.createWin32Process)(cmd, opts);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
return (0, posix_js_1.createPosixProcess)(cmd, opts);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Execute `command` with `options`. You should use this operation for processes
|
|
34
|
+
* that have a finite lifetime and on which you may wish to synchronize on the
|
|
35
|
+
* exit status. If you want to start a process like a server that spins up and runs
|
|
36
|
+
* forever, consider using `daemon()`
|
|
37
|
+
*/
|
|
38
|
+
function exec(command, options = {}) {
|
|
39
|
+
let [cmd, ...args] = options.shell ? [command] : (0, shellwords_1.split)(command);
|
|
40
|
+
let opts = { ...options, arguments: args.concat(options.arguments || []) };
|
|
41
|
+
return {
|
|
42
|
+
*[Symbol.iterator]() {
|
|
43
|
+
return yield* createProcess(cmd, opts);
|
|
44
|
+
},
|
|
45
|
+
*join() {
|
|
46
|
+
const process = yield* createProcess(cmd, opts);
|
|
47
|
+
let stdout = "";
|
|
48
|
+
let stderr = "";
|
|
49
|
+
yield* (0, effection_1.spawn)(function* () {
|
|
50
|
+
let subscription = yield* process.stdout;
|
|
51
|
+
let next = yield* subscription.next();
|
|
52
|
+
while (!next.done) {
|
|
53
|
+
stdout += next.value;
|
|
54
|
+
next = yield* subscription.next();
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
yield* (0, effection_1.spawn)(function* () {
|
|
58
|
+
let subscription = yield* process.stderr;
|
|
59
|
+
let next = yield* subscription.next();
|
|
60
|
+
while (!next.done) {
|
|
61
|
+
stderr += next.value;
|
|
62
|
+
next = yield* subscription.next();
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
let status = yield* process.join();
|
|
66
|
+
return { ...status, stdout, stderr };
|
|
67
|
+
},
|
|
68
|
+
*expect() {
|
|
69
|
+
const process = yield* createProcess(cmd, opts);
|
|
70
|
+
let stdout = "";
|
|
71
|
+
let stderr = "";
|
|
72
|
+
yield* (0, effection_1.spawn)(function* () {
|
|
73
|
+
let subscription = yield* process.stdout;
|
|
74
|
+
let next = yield* subscription.next();
|
|
75
|
+
while (!next.done) {
|
|
76
|
+
stdout += next.value;
|
|
77
|
+
next = yield* subscription.next();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
yield* (0, effection_1.spawn)(function* () {
|
|
81
|
+
let subscription = yield* process.stderr;
|
|
82
|
+
let next = yield* subscription.next();
|
|
83
|
+
while (!next.done) {
|
|
84
|
+
stderr += next.value;
|
|
85
|
+
next = yield* subscription.next();
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
let status = yield* process.expect();
|
|
89
|
+
return { ...status, stdout, stderr };
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type Operation, type Result, type Stream } from "effection";
|
|
2
|
+
import type { Readable } from "node:stream";
|
|
3
|
+
export type OutputStream = Stream<Uint8Array, void>;
|
|
4
|
+
export declare function useReadable(target: Readable | null): Stream<Uint8Array, void>;
|
|
5
|
+
interface Remainder<T> {
|
|
6
|
+
remainder: string;
|
|
7
|
+
result: T;
|
|
8
|
+
}
|
|
9
|
+
export declare function lines(): <T extends Uint8Array, TReturn>(stream: Stream<T, TReturn>) => Stream<string, Remainder<TReturn>>;
|
|
10
|
+
export declare function box<T>(op: () => Operation<T>): Operation<Result<T>>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EAEd,KAAK,MAAM,EACX,KAAK,MAAM,EACZ,MAAM,WAAW,CAAC;AACnB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;AAEpD,wBAAgB,WAAW,CACzB,MAAM,EAAE,QAAQ,GAAG,IAAI,GACtB,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAoB1B;AAED,UAAU,SAAS,CAAC,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,CAAC,CAAC;CACX;AAED,wBAAgB,KAAK,IAAI,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EACrD,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,KACvB,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,CAyCtC;AAED,wBAAiB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAOpE"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useReadable = useReadable;
|
|
4
|
+
exports.lines = lines;
|
|
5
|
+
exports.box = box;
|
|
6
|
+
const effection_1 = require("effection");
|
|
7
|
+
function useReadable(target) {
|
|
8
|
+
return (0, effection_1.resource)(function* (provide) {
|
|
9
|
+
let signal = (0, effection_1.createSignal)();
|
|
10
|
+
let listener = (chunk) => {
|
|
11
|
+
signal.send(chunk);
|
|
12
|
+
};
|
|
13
|
+
target?.on("data", listener);
|
|
14
|
+
target?.on("end", signal.close);
|
|
15
|
+
try {
|
|
16
|
+
yield* provide(yield* signal);
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
target?.off("data", listener);
|
|
20
|
+
target?.off("end", signal.close);
|
|
21
|
+
signal.close();
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function lines() {
|
|
26
|
+
const decoder = new TextDecoder();
|
|
27
|
+
return function (stream) {
|
|
28
|
+
return {
|
|
29
|
+
*[Symbol.iterator]() {
|
|
30
|
+
let subscription = yield* stream;
|
|
31
|
+
let buffer = [];
|
|
32
|
+
let remainder = "";
|
|
33
|
+
return {
|
|
34
|
+
*next() {
|
|
35
|
+
while (buffer.length === 0) {
|
|
36
|
+
let next = yield* subscription.next();
|
|
37
|
+
if (next.done) {
|
|
38
|
+
return {
|
|
39
|
+
done: true,
|
|
40
|
+
value: {
|
|
41
|
+
remainder,
|
|
42
|
+
result: next.value,
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
let current = remainder + decoder.decode(next.value);
|
|
48
|
+
let lines = current.split("\n");
|
|
49
|
+
if (lines.length > 0) {
|
|
50
|
+
buffer.push(...lines.slice(0, -1));
|
|
51
|
+
remainder = lines.slice(-1)[0];
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
remainder = current;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
done: false,
|
|
60
|
+
value: buffer.pop(),
|
|
61
|
+
};
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function* box(op) {
|
|
69
|
+
try {
|
|
70
|
+
let value = yield* op();
|
|
71
|
+
return (0, effection_1.Ok)(value);
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
return (0, effection_1.Err)(e);
|
|
75
|
+
}
|
|
76
|
+
}
|