@ricsam/r5d-worker 0.0.68 → 0.0.69
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/dist/cjs/main.cjs +13 -5
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/pty-output-coalescer.cjs +87 -0
- package/dist/mjs/main.mjs +13 -5
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/pty-output-coalescer.mjs +61 -0
- package/dist/types/pty-output-coalescer.d.ts +20 -0
- package/package.json +1 -1
package/dist/cjs/main.cjs
CHANGED
|
@@ -62,6 +62,7 @@ var import_cli_update = require("./cli-update.cjs");
|
|
|
62
62
|
var import_git_identity = require("./git-identity.cjs");
|
|
63
63
|
var import_heartbeat = require("./heartbeat.cjs");
|
|
64
64
|
var import_process_tree = require("./process-tree.cjs");
|
|
65
|
+
var import_pty_output_coalescer = require("./pty-output-coalescer.cjs");
|
|
65
66
|
var import_port_forward_client = require("./port-forward-client.cjs");
|
|
66
67
|
var import_workspace_incident_state = require("./workspace-incident-state.cjs");
|
|
67
68
|
var import_workspace_command_sync_policy = require("./workspace-command-sync-policy.cjs");
|
|
@@ -2308,6 +2309,15 @@ async function openPty(input) {
|
|
|
2308
2309
|
}) : {};
|
|
2309
2310
|
const targetProcessEnv = targetIdentityEnv(input.resolvedTarget.target);
|
|
2310
2311
|
const shell = resolveHostShell(input.message.command);
|
|
2312
|
+
const outputCoalescer = (0, import_pty_output_coalescer.createPtyOutputCoalescer)({
|
|
2313
|
+
send: (data) => {
|
|
2314
|
+
sendWorkerMessage(input.ws, {
|
|
2315
|
+
type: "pty_output",
|
|
2316
|
+
ptyId: input.message.ptyId,
|
|
2317
|
+
data
|
|
2318
|
+
});
|
|
2319
|
+
}
|
|
2320
|
+
});
|
|
2311
2321
|
const ptyProcess = createNodePtyBridge({
|
|
2312
2322
|
file: shell.file,
|
|
2313
2323
|
args: shell.args,
|
|
@@ -2332,13 +2342,10 @@ async function openPty(input) {
|
|
|
2332
2342
|
});
|
|
2333
2343
|
},
|
|
2334
2344
|
onOutput: (data) => {
|
|
2335
|
-
|
|
2336
|
-
type: "pty_output",
|
|
2337
|
-
ptyId: input.message.ptyId,
|
|
2338
|
-
data
|
|
2339
|
-
});
|
|
2345
|
+
outputCoalescer.push(data);
|
|
2340
2346
|
},
|
|
2341
2347
|
onExit: (event) => {
|
|
2348
|
+
outputCoalescer.flush();
|
|
2342
2349
|
input.releaseWorkspaceMutation?.();
|
|
2343
2350
|
activePtys.delete(input.message.ptyId);
|
|
2344
2351
|
input.onTerminal?.();
|
|
@@ -2350,6 +2357,7 @@ async function openPty(input) {
|
|
|
2350
2357
|
});
|
|
2351
2358
|
},
|
|
2352
2359
|
onError: (error) => {
|
|
2360
|
+
outputCoalescer.flush();
|
|
2353
2361
|
input.releaseWorkspaceMutation?.();
|
|
2354
2362
|
activePtys.delete(input.message.ptyId);
|
|
2355
2363
|
input.onTerminal?.();
|
package/dist/cjs/package.json
CHANGED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var pty_output_coalescer_exports = {};
|
|
20
|
+
__export(pty_output_coalescer_exports, {
|
|
21
|
+
DEFAULT_PTY_OUTPUT_FLUSH_INTERVAL_MS: () => DEFAULT_PTY_OUTPUT_FLUSH_INTERVAL_MS,
|
|
22
|
+
DEFAULT_PTY_OUTPUT_MAX_BUFFER_BYTES: () => DEFAULT_PTY_OUTPUT_MAX_BUFFER_BYTES,
|
|
23
|
+
createPtyOutputCoalescer: () => createPtyOutputCoalescer
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(pty_output_coalescer_exports);
|
|
26
|
+
const DEFAULT_PTY_OUTPUT_FLUSH_INTERVAL_MS = 8;
|
|
27
|
+
const DEFAULT_PTY_OUTPUT_MAX_BUFFER_BYTES = 64 * 1024;
|
|
28
|
+
function defaultSchedule(callback, delayMs) {
|
|
29
|
+
const timer = setTimeout(callback, delayMs);
|
|
30
|
+
timer.unref();
|
|
31
|
+
return () => clearTimeout(timer);
|
|
32
|
+
}
|
|
33
|
+
function createPtyOutputCoalescer(options) {
|
|
34
|
+
const flushIntervalMs = options.flushIntervalMs ?? DEFAULT_PTY_OUTPUT_FLUSH_INTERVAL_MS;
|
|
35
|
+
const maxBufferBytes = options.maxBufferBytes ?? DEFAULT_PTY_OUTPUT_MAX_BUFFER_BYTES;
|
|
36
|
+
const now = options.now ?? Date.now;
|
|
37
|
+
const schedule = options.schedule ?? defaultSchedule;
|
|
38
|
+
let buffer = "";
|
|
39
|
+
let bufferedBytes = 0;
|
|
40
|
+
let cancelScheduledFlush = null;
|
|
41
|
+
let lastSendAt = Number.NEGATIVE_INFINITY;
|
|
42
|
+
const sendNow = (data) => {
|
|
43
|
+
lastSendAt = now();
|
|
44
|
+
options.send(data);
|
|
45
|
+
};
|
|
46
|
+
const flush = () => {
|
|
47
|
+
if (cancelScheduledFlush) {
|
|
48
|
+
cancelScheduledFlush();
|
|
49
|
+
cancelScheduledFlush = null;
|
|
50
|
+
}
|
|
51
|
+
if (bufferedBytes === 0) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const data = buffer;
|
|
55
|
+
buffer = "";
|
|
56
|
+
bufferedBytes = 0;
|
|
57
|
+
sendNow(data);
|
|
58
|
+
};
|
|
59
|
+
const push = (data) => {
|
|
60
|
+
if (data.length === 0) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (bufferedBytes === 0 && now() - lastSendAt >= flushIntervalMs) {
|
|
64
|
+
sendNow(data);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
buffer += data;
|
|
68
|
+
bufferedBytes += Buffer.byteLength(data, "utf8");
|
|
69
|
+
if (bufferedBytes >= maxBufferBytes) {
|
|
70
|
+
flush();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (!cancelScheduledFlush) {
|
|
74
|
+
cancelScheduledFlush = schedule(() => {
|
|
75
|
+
cancelScheduledFlush = null;
|
|
76
|
+
flush();
|
|
77
|
+
}, flushIntervalMs);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
return { push, flush };
|
|
81
|
+
}
|
|
82
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
83
|
+
0 && (module.exports = {
|
|
84
|
+
DEFAULT_PTY_OUTPUT_FLUSH_INTERVAL_MS,
|
|
85
|
+
DEFAULT_PTY_OUTPUT_MAX_BUFFER_BYTES,
|
|
86
|
+
createPtyOutputCoalescer
|
|
87
|
+
});
|
package/dist/mjs/main.mjs
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
WORKER_HEARTBEAT_INTERVAL_MS
|
|
13
13
|
} from "./heartbeat.mjs";
|
|
14
14
|
import { terminateProcessTree } from "./process-tree.mjs";
|
|
15
|
+
import { createPtyOutputCoalescer } from "./pty-output-coalescer.mjs";
|
|
15
16
|
import { openWorkerPortForwardRelay } from "./port-forward-client.mjs";
|
|
16
17
|
import { applyWorkspaceIncidentUpdate, releasePendingWorkspaceHead, WorkspaceIncidentOrderingFence } from "./workspace-incident-state.mjs";
|
|
17
18
|
import { acquireWorkspaceCommandMutation, runWorkspaceCommand } from "./workspace-command-sync-policy.mjs";
|
|
@@ -2279,6 +2280,15 @@ async function openPty(input) {
|
|
|
2279
2280
|
}) : {};
|
|
2280
2281
|
const targetProcessEnv = targetIdentityEnv(input.resolvedTarget.target);
|
|
2281
2282
|
const shell = resolveHostShell(input.message.command);
|
|
2283
|
+
const outputCoalescer = createPtyOutputCoalescer({
|
|
2284
|
+
send: (data) => {
|
|
2285
|
+
sendWorkerMessage(input.ws, {
|
|
2286
|
+
type: "pty_output",
|
|
2287
|
+
ptyId: input.message.ptyId,
|
|
2288
|
+
data
|
|
2289
|
+
});
|
|
2290
|
+
}
|
|
2291
|
+
});
|
|
2282
2292
|
const ptyProcess = createNodePtyBridge({
|
|
2283
2293
|
file: shell.file,
|
|
2284
2294
|
args: shell.args,
|
|
@@ -2303,13 +2313,10 @@ async function openPty(input) {
|
|
|
2303
2313
|
});
|
|
2304
2314
|
},
|
|
2305
2315
|
onOutput: (data) => {
|
|
2306
|
-
|
|
2307
|
-
type: "pty_output",
|
|
2308
|
-
ptyId: input.message.ptyId,
|
|
2309
|
-
data
|
|
2310
|
-
});
|
|
2316
|
+
outputCoalescer.push(data);
|
|
2311
2317
|
},
|
|
2312
2318
|
onExit: (event) => {
|
|
2319
|
+
outputCoalescer.flush();
|
|
2313
2320
|
input.releaseWorkspaceMutation?.();
|
|
2314
2321
|
activePtys.delete(input.message.ptyId);
|
|
2315
2322
|
input.onTerminal?.();
|
|
@@ -2321,6 +2328,7 @@ async function openPty(input) {
|
|
|
2321
2328
|
});
|
|
2322
2329
|
},
|
|
2323
2330
|
onError: (error) => {
|
|
2331
|
+
outputCoalescer.flush();
|
|
2324
2332
|
input.releaseWorkspaceMutation?.();
|
|
2325
2333
|
activePtys.delete(input.message.ptyId);
|
|
2326
2334
|
input.onTerminal?.();
|
package/dist/mjs/package.json
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
const DEFAULT_PTY_OUTPUT_FLUSH_INTERVAL_MS = 8;
|
|
2
|
+
const DEFAULT_PTY_OUTPUT_MAX_BUFFER_BYTES = 64 * 1024;
|
|
3
|
+
function defaultSchedule(callback, delayMs) {
|
|
4
|
+
const timer = setTimeout(callback, delayMs);
|
|
5
|
+
timer.unref();
|
|
6
|
+
return () => clearTimeout(timer);
|
|
7
|
+
}
|
|
8
|
+
function createPtyOutputCoalescer(options) {
|
|
9
|
+
const flushIntervalMs = options.flushIntervalMs ?? DEFAULT_PTY_OUTPUT_FLUSH_INTERVAL_MS;
|
|
10
|
+
const maxBufferBytes = options.maxBufferBytes ?? DEFAULT_PTY_OUTPUT_MAX_BUFFER_BYTES;
|
|
11
|
+
const now = options.now ?? Date.now;
|
|
12
|
+
const schedule = options.schedule ?? defaultSchedule;
|
|
13
|
+
let buffer = "";
|
|
14
|
+
let bufferedBytes = 0;
|
|
15
|
+
let cancelScheduledFlush = null;
|
|
16
|
+
let lastSendAt = Number.NEGATIVE_INFINITY;
|
|
17
|
+
const sendNow = (data) => {
|
|
18
|
+
lastSendAt = now();
|
|
19
|
+
options.send(data);
|
|
20
|
+
};
|
|
21
|
+
const flush = () => {
|
|
22
|
+
if (cancelScheduledFlush) {
|
|
23
|
+
cancelScheduledFlush();
|
|
24
|
+
cancelScheduledFlush = null;
|
|
25
|
+
}
|
|
26
|
+
if (bufferedBytes === 0) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const data = buffer;
|
|
30
|
+
buffer = "";
|
|
31
|
+
bufferedBytes = 0;
|
|
32
|
+
sendNow(data);
|
|
33
|
+
};
|
|
34
|
+
const push = (data) => {
|
|
35
|
+
if (data.length === 0) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (bufferedBytes === 0 && now() - lastSendAt >= flushIntervalMs) {
|
|
39
|
+
sendNow(data);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
buffer += data;
|
|
43
|
+
bufferedBytes += Buffer.byteLength(data, "utf8");
|
|
44
|
+
if (bufferedBytes >= maxBufferBytes) {
|
|
45
|
+
flush();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (!cancelScheduledFlush) {
|
|
49
|
+
cancelScheduledFlush = schedule(() => {
|
|
50
|
+
cancelScheduledFlush = null;
|
|
51
|
+
flush();
|
|
52
|
+
}, flushIntervalMs);
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
return { push, flush };
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
DEFAULT_PTY_OUTPUT_FLUSH_INTERVAL_MS,
|
|
59
|
+
DEFAULT_PTY_OUTPUT_MAX_BUFFER_BYTES,
|
|
60
|
+
createPtyOutputCoalescer
|
|
61
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface PtyOutputCoalescerOptions {
|
|
2
|
+
send: (data: string) => void;
|
|
3
|
+
flushIntervalMs?: number;
|
|
4
|
+
maxBufferBytes?: number;
|
|
5
|
+
now?: () => number;
|
|
6
|
+
schedule?: (callback: () => void, delayMs: number) => () => void;
|
|
7
|
+
}
|
|
8
|
+
export interface PtyOutputCoalescer {
|
|
9
|
+
push(data: string): void;
|
|
10
|
+
flush(): void;
|
|
11
|
+
}
|
|
12
|
+
export declare const DEFAULT_PTY_OUTPUT_FLUSH_INTERVAL_MS = 8;
|
|
13
|
+
export declare const DEFAULT_PTY_OUTPUT_MAX_BUFFER_BYTES: number;
|
|
14
|
+
/**
|
|
15
|
+
* Batches PTY output into fewer, larger relay messages. An isolated chunk
|
|
16
|
+
* (an interactive keystroke echo) is sent immediately so coalescing adds no
|
|
17
|
+
* input latency; only sustained bursts (build logs, `cat` of a large file)
|
|
18
|
+
* are buffered, bounded by the flush interval and the buffer byte cap.
|
|
19
|
+
*/
|
|
20
|
+
export declare function createPtyOutputCoalescer(options: PtyOutputCoalescerOptions): PtyOutputCoalescer;
|