@opensumi/ide-terminal-next 2.17.8 → 2.18.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.
Files changed (154) hide show
  1. package/lib/browser/component/tab.item.d.ts.map +1 -1
  2. package/lib/browser/component/tab.item.js +33 -12
  3. package/lib/browser/component/tab.item.js.map +1 -1
  4. package/lib/browser/component/tab.module.less +41 -12
  5. package/lib/browser/component/tab.view.d.ts.map +1 -1
  6. package/lib/browser/component/tab.view.js +25 -7
  7. package/lib/browser/component/tab.view.js.map +1 -1
  8. package/lib/browser/component/terminal.view.d.ts.map +1 -1
  9. package/lib/browser/component/terminal.view.js +25 -24
  10. package/lib/browser/component/terminal.view.js.map +1 -1
  11. package/lib/browser/contribution/terminal.menu.d.ts.map +1 -1
  12. package/lib/browser/contribution/terminal.menu.js +3 -4
  13. package/lib/browser/contribution/terminal.menu.js.map +1 -1
  14. package/lib/browser/index.d.ts.map +1 -1
  15. package/lib/browser/index.js +0 -5
  16. package/lib/browser/index.js.map +1 -1
  17. package/lib/browser/links/link-manager.d.ts.map +1 -1
  18. package/lib/browser/links/link-manager.js +11 -12
  19. package/lib/browser/links/link-manager.js.map +1 -1
  20. package/lib/browser/links/validated-local-link-provider.d.ts.map +1 -1
  21. package/lib/browser/links/validated-local-link-provider.js +1 -2
  22. package/lib/browser/links/validated-local-link-provider.js.map +1 -1
  23. package/lib/browser/terminal.addon.d.ts.map +1 -1
  24. package/lib/browser/terminal.addon.js +3 -1
  25. package/lib/browser/terminal.addon.js.map +1 -1
  26. package/lib/browser/terminal.api.d.ts +4 -2
  27. package/lib/browser/terminal.api.d.ts.map +1 -1
  28. package/lib/browser/terminal.api.js +7 -1
  29. package/lib/browser/terminal.api.js.map +1 -1
  30. package/lib/browser/terminal.client.d.ts +7 -4
  31. package/lib/browser/terminal.client.d.ts.map +1 -1
  32. package/lib/browser/terminal.client.js +20 -45
  33. package/lib/browser/terminal.client.js.map +1 -1
  34. package/lib/browser/terminal.context-menu.d.ts +2 -0
  35. package/lib/browser/terminal.context-menu.d.ts.map +1 -1
  36. package/lib/browser/terminal.context-menu.js +23 -4
  37. package/lib/browser/terminal.context-menu.js.map +1 -1
  38. package/lib/browser/terminal.controller.d.ts +16 -3
  39. package/lib/browser/terminal.controller.d.ts.map +1 -1
  40. package/lib/browser/terminal.controller.js +161 -27
  41. package/lib/browser/terminal.controller.js.map +1 -1
  42. package/lib/browser/terminal.input.js +2 -2
  43. package/lib/browser/terminal.input.js.map +1 -1
  44. package/lib/browser/terminal.internal.service.d.ts +6 -6
  45. package/lib/browser/terminal.internal.service.d.ts.map +1 -1
  46. package/lib/browser/terminal.internal.service.js +4 -23
  47. package/lib/browser/terminal.internal.service.js.map +1 -1
  48. package/lib/browser/terminal.profile.d.ts +18 -9
  49. package/lib/browser/terminal.profile.d.ts.map +1 -1
  50. package/lib/browser/terminal.profile.internal.d.ts.map +1 -1
  51. package/lib/browser/terminal.profile.internal.js +4 -6
  52. package/lib/browser/terminal.profile.internal.js.map +1 -1
  53. package/lib/browser/terminal.profile.js +59 -9
  54. package/lib/browser/terminal.profile.js.map +1 -1
  55. package/lib/browser/terminal.restore.d.ts.map +1 -1
  56. package/lib/browser/terminal.restore.js +3 -1
  57. package/lib/browser/terminal.restore.js.map +1 -1
  58. package/lib/browser/terminal.search.d.ts.map +1 -1
  59. package/lib/browser/terminal.search.js +6 -0
  60. package/lib/browser/terminal.search.js.map +1 -1
  61. package/lib/browser/terminal.service.d.ts +5 -17
  62. package/lib/browser/terminal.service.d.ts.map +1 -1
  63. package/lib/browser/terminal.service.js +6 -79
  64. package/lib/browser/terminal.service.js.map +1 -1
  65. package/lib/browser/terminal.view.d.ts +5 -3
  66. package/lib/browser/terminal.view.d.ts.map +1 -1
  67. package/lib/browser/terminal.view.js +9 -5
  68. package/lib/browser/terminal.view.js.map +1 -1
  69. package/lib/browser/xterm.d.ts +2 -1
  70. package/lib/browser/xterm.d.ts.map +1 -1
  71. package/lib/browser/xterm.js.map +1 -1
  72. package/lib/common/api.d.ts +3 -2
  73. package/lib/common/api.d.ts.map +1 -1
  74. package/lib/common/client.d.ts +17 -0
  75. package/lib/common/client.d.ts.map +1 -1
  76. package/lib/common/client.js +2 -1
  77. package/lib/common/client.js.map +1 -1
  78. package/lib/common/controller.d.ts +20 -5
  79. package/lib/common/controller.d.ts.map +1 -1
  80. package/lib/common/controller.js.map +1 -1
  81. package/lib/common/environmentVariable.d.ts +2 -3
  82. package/lib/common/environmentVariable.d.ts.map +1 -1
  83. package/lib/common/environmentVariable.js.map +1 -1
  84. package/lib/common/environmentVariableCollection.d.ts +2 -3
  85. package/lib/common/environmentVariableCollection.d.ts.map +1 -1
  86. package/lib/common/environmentVariableCollection.js +2 -2
  87. package/lib/common/environmentVariableCollection.js.map +1 -1
  88. package/lib/common/profile.d.ts +6 -9
  89. package/lib/common/profile.d.ts.map +1 -1
  90. package/lib/common/profile.js +1 -2
  91. package/lib/common/profile.js.map +1 -1
  92. package/lib/common/pty.d.ts +91 -11
  93. package/lib/common/pty.d.ts.map +1 -1
  94. package/lib/common/pty.js +40 -1
  95. package/lib/common/pty.js.map +1 -1
  96. package/lib/common/render.d.ts +5 -0
  97. package/lib/common/render.d.ts.map +1 -1
  98. package/lib/common/render.js.map +1 -1
  99. package/lib/common/resize.d.ts +2 -0
  100. package/lib/common/resize.d.ts.map +1 -1
  101. package/lib/common/service.d.ts +8 -11
  102. package/lib/common/service.d.ts.map +1 -1
  103. package/lib/common/service.js.map +1 -1
  104. package/lib/common/xterm.d.ts +16 -0
  105. package/lib/common/xterm.d.ts.map +1 -0
  106. package/lib/common/xterm.js +3 -0
  107. package/lib/common/xterm.js.map +1 -0
  108. package/lib/node/index.d.ts.map +1 -1
  109. package/lib/node/index.js +5 -0
  110. package/lib/node/index.js.map +1 -1
  111. package/lib/node/pty.d.ts +9 -5
  112. package/lib/node/pty.d.ts.map +1 -1
  113. package/lib/node/pty.js +13 -10
  114. package/lib/node/pty.js.map +1 -1
  115. package/lib/node/pty.manager.d.ts +52 -0
  116. package/lib/node/pty.manager.d.ts.map +1 -0
  117. package/lib/node/pty.manager.js +149 -0
  118. package/lib/node/pty.manager.js.map +1 -0
  119. package/lib/node/pty.manager.remote.d.ts +10 -0
  120. package/lib/node/pty.manager.remote.d.ts.map +1 -0
  121. package/lib/node/pty.manager.remote.js +92 -0
  122. package/lib/node/pty.manager.remote.js.map +1 -0
  123. package/lib/node/pty.proxy.d.ts +45 -0
  124. package/lib/node/pty.proxy.d.ts.map +1 -0
  125. package/lib/node/pty.proxy.js +255 -0
  126. package/lib/node/pty.proxy.js.map +1 -0
  127. package/lib/node/pty.proxy.remote.exec.d.ts +2 -0
  128. package/lib/node/pty.proxy.remote.exec.d.ts.map +1 -0
  129. package/lib/node/pty.proxy.remote.exec.js +7 -0
  130. package/lib/node/pty.proxy.remote.exec.js.map +1 -0
  131. package/lib/node/shell.d.ts +1 -1
  132. package/lib/node/shell.d.ts.map +1 -1
  133. package/lib/node/shell.js +14 -15
  134. package/lib/node/shell.js.map +1 -1
  135. package/lib/node/terminal.profile.service.d.ts.map +1 -1
  136. package/lib/node/terminal.profile.service.js +4 -6
  137. package/lib/node/terminal.profile.service.js.map +1 -1
  138. package/lib/node/terminal.service.client.d.ts +3 -8
  139. package/lib/node/terminal.service.client.d.ts.map +1 -1
  140. package/lib/node/terminal.service.client.js +8 -39
  141. package/lib/node/terminal.service.client.js.map +1 -1
  142. package/lib/node/terminal.service.d.ts +3 -2
  143. package/lib/node/terminal.service.d.ts.map +1 -1
  144. package/lib/node/terminal.service.js +36 -10
  145. package/lib/node/terminal.service.js.map +1 -1
  146. package/package.json +16 -16
  147. package/lib/browser/terminal.contribution.d.ts +0 -7
  148. package/lib/browser/terminal.contribution.d.ts.map +0 -1
  149. package/lib/browser/terminal.contribution.js +0 -32
  150. package/lib/browser/terminal.contribution.js.map +0 -1
  151. package/lib/common/menu.d.ts +0 -5
  152. package/lib/common/menu.d.ts.map +0 -1
  153. package/lib/common/menu.js +0 -9
  154. package/lib/common/menu.js.map +0 -1
@@ -0,0 +1,52 @@
1
+ import * as pty from 'node-pty';
2
+ import { INodeLogger } from '@opensumi/ide-core-node';
3
+ import { IPtyProcessProxy, IPtyProxyRPCService } from '../common';
4
+ export declare const PtyServiceManagerToken: unique symbol;
5
+ /**
6
+ * 在 IDE 容器中运行,具体分为两类实现。通过 DI 注入替换来做到两种模式的替换
7
+ * 1.与远程容器通信,完成终端的创建连接一些列事情 - 双容器架构
8
+ * 2.直接走同进程调用,操作终端 - 传统架构
9
+ */
10
+ export interface IPtyServiceManager {
11
+ spawn(file: string, args: string[] | string, options: pty.IPtyForkOptions | pty.IWindowsPtyForkOptions, sessionId?: string): Promise<IPtyProcessProxy>;
12
+ onData(pid: number, listener: (e: string) => any): pty.IDisposable;
13
+ onExit(pid: number, listener: (e: {
14
+ exitCode: number;
15
+ signal?: number;
16
+ }) => any): pty.IDisposable;
17
+ on(pid: number, event: 'data', listener: (data: string) => void): void;
18
+ on(pid: number, event: 'exit', listener: (exitCode: number, signal?: number) => void): void;
19
+ on(pid: number, event: any, listener: (data: any) => void): void;
20
+ resize(pid: number, columns: number, rows: number): void;
21
+ write(pid: number, data: string): void;
22
+ pause(pid: number): void;
23
+ resume(pid: number): void;
24
+ kill(pid: number, signal?: string): void;
25
+ getProcess(pid: any): Promise<string>;
26
+ checkSession(sessionId: string): Promise<boolean>;
27
+ }
28
+ export declare class PtyServiceManager implements IPtyServiceManager {
29
+ protected callId: number;
30
+ protected callbackMap: Map<number, (...args: any[]) => void>;
31
+ protected ptyServiceProxy: IPtyProxyRPCService;
32
+ protected logger: INodeLogger;
33
+ constructor();
34
+ protected initLocal(): void;
35
+ private addNewCallback;
36
+ spawn(file: string, args: string[] | string, options: pty.IPtyForkOptions | pty.IWindowsPtyForkOptions, sessionId?: string): Promise<IPtyProcessProxy>;
37
+ getProcess(pid: any): Promise<string>;
38
+ onData(pid: number, listener: (e: string) => any): pty.IDisposable;
39
+ onExit(pid: number, listener: (e: {
40
+ exitCode: number;
41
+ signal?: number;
42
+ }) => any): pty.IDisposable;
43
+ on(pid: number, event: 'data', listener: (data: string) => void): void;
44
+ on(pid: number, event: 'exit', listener: (exitCode: number, signal?: number) => void): void;
45
+ resize(pid: number, columns: number, rows: number): void;
46
+ write(pid: number, data: string): void;
47
+ kill(pid: number, signal?: string): void;
48
+ pause(pid: number): void;
49
+ resume(pid: number): void;
50
+ checkSession(sessionId: string): Promise<boolean>;
51
+ }
52
+ //# sourceMappingURL=pty.manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty.manager.d.ts","sourceRoot":"","sources":["../../src/node/pty.manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PtyServiceManager = exports.PtyServiceManagerToken = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const di_1 = require("@opensumi/di");
6
+ const ide_core_node_1 = require("@opensumi/ide-core-node");
7
+ const pty_proxy_1 = require("./pty.proxy");
8
+ exports.PtyServiceManagerToken = Symbol('PtyServiceManager');
9
+ // 记录终端输入到输出的时间戳,主要是用于统计 Pty 处理 + IDE <--> Pty 的IPC 耗时
10
+ let timeCaptureTmp = 0;
11
+ // 终端的命令可能会有多行输出,避免后面几次输出也被用于时间差计算统计,因此一次 write,一次统计
12
+ let timeCaptureFilter = false;
13
+ // 标准单容器架构 - 在 IDE 容器中运行,PtyService 也在 IDE 进程中运行
14
+ // 如果需要用到双容器远程架构,可以查看 PtyServiceManagerRemote 的实现
15
+ let PtyServiceManager = class PtyServiceManager {
16
+ // Pty 运行在 IDE Server 上,因此可以直接调用
17
+ constructor() {
18
+ this.callId = 0;
19
+ this.callbackMap = new Map();
20
+ this.initLocal();
21
+ }
22
+ initLocal() {
23
+ const callback = async (callId, ...args) => {
24
+ const callback = this.callbackMap.get(callId);
25
+ if (!callback) {
26
+ return Promise.reject(new Error(`no found callback: ${callId}`));
27
+ }
28
+ callback(...args);
29
+ };
30
+ this.ptyServiceProxy = new pty_proxy_1.PtyServiceProxy(callback);
31
+ }
32
+ // 维护一个 CallbackMap,用于在 PtyServiceProxy 中远程调用回调
33
+ // 因为在 RPC 调用中本身是没法直接传递回调 Function 的,所以需要在远程调用中传递 callId,在本地调用中通过 callId 获取回调
34
+ addNewCallback(pid, callback) {
35
+ const callId = this.callId++;
36
+ this.callbackMap.set(callId, callback);
37
+ const disposable = {
38
+ dispose: () => {
39
+ this.callbackMap.delete(callId);
40
+ },
41
+ };
42
+ return { callId, disposable };
43
+ }
44
+ async spawn(file, args, options, sessionId) {
45
+ const iPtyRemoteProxy = (await this.ptyServiceProxy.$spawn(file, args, options, sessionId));
46
+ // 局部功能的 Ipty, 代理所有常量
47
+ return new PtyProcessProxy(iPtyRemoteProxy, this);
48
+ }
49
+ async getProcess(pid) {
50
+ return await this.ptyServiceProxy.$getProcess(pid);
51
+ }
52
+ // 实现 Ipty 的需要回调的逻辑接口,同时注入
53
+ onData(pid, listener) {
54
+ const monitorListener = (resString) => {
55
+ listener(resString);
56
+ if (timeCaptureFilter) {
57
+ const timeDiff = new Date().getTime() - timeCaptureTmp;
58
+ this.logger.log(`PtyServiceManager.onData: ${timeDiff}ms data: ${resString.substring(0, 100)}`);
59
+ timeCaptureFilter = false;
60
+ }
61
+ };
62
+ const { callId, disposable } = this.addNewCallback(pid, monitorListener);
63
+ this.ptyServiceProxy.$onData(callId, pid);
64
+ return disposable;
65
+ }
66
+ onExit(pid, listener) {
67
+ const { callId, disposable } = this.addNewCallback(pid, listener);
68
+ this.ptyServiceProxy.$onExit(callId, pid);
69
+ return disposable;
70
+ }
71
+ on(pid, event, listener) {
72
+ const { callId } = this.addNewCallback(pid, listener);
73
+ this.ptyServiceProxy.$on(callId, pid, event);
74
+ }
75
+ resize(pid, columns, rows) {
76
+ this.ptyServiceProxy.$resize(pid, columns, rows);
77
+ }
78
+ write(pid, data) {
79
+ timeCaptureTmp = new Date().getTime();
80
+ if (data.includes('=')) {
81
+ // 使用 '=' 作为触发本地通信统计的标识
82
+ timeCaptureFilter = true;
83
+ }
84
+ this.ptyServiceProxy.$write(pid, data);
85
+ }
86
+ kill(pid, signal) {
87
+ this.ptyServiceProxy.$kill(pid, signal);
88
+ }
89
+ pause(pid) {
90
+ this.ptyServiceProxy.$pause(pid);
91
+ }
92
+ resume(pid) {
93
+ this.ptyServiceProxy.$resume(pid);
94
+ }
95
+ async checkSession(sessionId) {
96
+ return await this.ptyServiceProxy.$checkSession(sessionId);
97
+ }
98
+ };
99
+ tslib_1.__decorate([
100
+ (0, di_1.Autowired)(ide_core_node_1.INodeLogger),
101
+ tslib_1.__metadata("design:type", Object)
102
+ ], PtyServiceManager.prototype, "logger", void 0);
103
+ PtyServiceManager = tslib_1.__decorate([
104
+ (0, di_1.Injectable)(),
105
+ tslib_1.__metadata("design:paramtypes", [])
106
+ ], PtyServiceManager);
107
+ exports.PtyServiceManager = PtyServiceManager;
108
+ // Pty 进程的 Remote 代理
109
+ // 实现了 IPtyProcessProxy 背后是 NodePty 的 INodePty, 因此可以做到和本地化直接调用 NodePty 的代码兼容
110
+ class PtyProcessProxy {
111
+ constructor(iptyProxy, ptyServiceManager) {
112
+ this.ptyServiceManager = ptyServiceManager;
113
+ this.pid = iptyProxy.pid;
114
+ this.cols = iptyProxy.cols;
115
+ this.rows = iptyProxy.rows;
116
+ this._process = iptyProxy.process;
117
+ this.handleFlowControl = iptyProxy.handleFlowControl;
118
+ this.onData = (listener) => this.ptyServiceManager.onData(this.pid, listener);
119
+ this.onExit = (listener) => this.ptyServiceManager.onExit(this.pid, listener);
120
+ }
121
+ get process() {
122
+ return this._process;
123
+ }
124
+ // 获取实时的ProcessName
125
+ async getProcessDynamically() {
126
+ const process = await this.ptyServiceManager.getProcess(this.pid);
127
+ this._process = process;
128
+ return process;
129
+ }
130
+ on(event, listener) {
131
+ this.ptyServiceManager.on(this.pid, event, listener);
132
+ }
133
+ resize(columns, rows) {
134
+ this.ptyServiceManager.resize(this.pid, columns, rows);
135
+ }
136
+ write(data) {
137
+ this.ptyServiceManager.write(this.pid, data);
138
+ }
139
+ kill(signal) {
140
+ this.ptyServiceManager.kill(this.pid, signal);
141
+ }
142
+ pause() {
143
+ this.ptyServiceManager.pause(this.pid);
144
+ }
145
+ resume() {
146
+ this.ptyServiceManager.resume(this.pid);
147
+ }
148
+ }
149
+ //# sourceMappingURL=pty.manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty.manager.js","sourceRoot":"","sources":["../../src/node/pty.manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /// <reference types="node" />
2
+ import { SocketConnectOpts } from 'net';
3
+ import { PtyServiceManager } from './pty.manager';
4
+ export declare class PtyServiceManagerRemote extends PtyServiceManager {
5
+ constructor(connectOpts?: SocketConnectOpts);
6
+ private initRPCService;
7
+ private initRemoteConnectionMode;
8
+ protected initLocal(): void;
9
+ }
10
+ //# sourceMappingURL=pty.manager.remote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty.manager.remote.d.ts","sourceRoot":"","sources":["../../src/node/pty.manager.remote.ts"],"names":[],"mappings":";AAAA,OAAY,EAAE,iBAAiB,EAAE,MAAM,KAAK,CAAC;AAc7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAKlD,qBACa,uBAAwB,SAAQ,iBAAiB;gBAEpC,WAAW,GAAE,iBAA2D;IAKhG,OAAO,CAAC,cAAc;IAiCtB,OAAO,CAAC,wBAAwB;IAgChC,SAAS,CAAC,SAAS;CAGpB"}
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PtyServiceManagerRemote = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const net_1 = tslib_1.__importDefault(require("net"));
6
+ const di_1 = require("@opensumi/di");
7
+ const ide_connection_1 = require("@opensumi/ide-connection");
8
+ const node_1 = require("@opensumi/ide-connection/lib/node");
9
+ const ide_core_common_1 = require("@opensumi/ide-core-common");
10
+ const common_1 = require("../common");
11
+ const pty_manager_1 = require("./pty.manager");
12
+ // 双容器架构 - 在IDE容器中远程运行,与DEV Server上的PtyService通信
13
+ // 继承自PtyServiceManager,覆写了创建PtyProxyService连接的方法,用于需要远程连接PtyService的场景
14
+ // 具体需要根据应用场景,通过DI注入覆盖PtyServiceManager使用
15
+ let PtyServiceManagerRemote = class PtyServiceManagerRemote extends pty_manager_1.PtyServiceManager {
16
+ // Pty运行在单独的容器上,通过Socket连接,可以自定义Socket连接参数
17
+ constructor(connectOpts = { port: common_1.PTY_SERVICE_PROXY_SERVER_PORT }) {
18
+ super();
19
+ this.initRemoteConnectionMode(connectOpts);
20
+ }
21
+ initRPCService(socket) {
22
+ const clientCenter = new ide_connection_1.RPCServiceCenter();
23
+ const { getRPCService: clientGetRPCService, createRPCService } = (0, ide_connection_1.initRPCService)(clientCenter);
24
+ const getService = clientGetRPCService(common_1.PTY_SERVICE_PROXY_PROTOCOL);
25
+ this.ptyServiceProxy = getService;
26
+ let callbackDisposed = false;
27
+ // 处理回调
28
+ createRPCService(common_1.PTY_SERVICE_PROXY_CALLBACK_PROTOCOL, {
29
+ $callback: async (callId, ...args) => {
30
+ if (callbackDisposed) {
31
+ // 在这里做一下Dispose的处理,在Dispose之后回调不再被执行
32
+ // TODO: 但是按照我的理解,在removeConnection之后这里就完全不应该被执行,但却被执行了,是为什么呢?
33
+ return;
34
+ }
35
+ const callback = this.callbackMap.get(callId);
36
+ if (!callback) {
37
+ // 这里callbackMap的callId对应的回调方法被注销,但是依然被调用了,这种情况不应该发生
38
+ this.logger.warn('PtyServiceManager not found callback:', callId);
39
+ }
40
+ else {
41
+ callback(...args);
42
+ }
43
+ },
44
+ });
45
+ const messageConnection = (0, node_1.createSocketConnection)(socket);
46
+ clientCenter.setConnection(messageConnection);
47
+ return ide_core_common_1.Disposable.create(() => {
48
+ callbackDisposed = true;
49
+ clientCenter.removeConnection(messageConnection);
50
+ });
51
+ }
52
+ initRemoteConnectionMode(connectOpts) {
53
+ const socket = new net_1.default.Socket();
54
+ let rpcServiceDisposable;
55
+ // UNIX Socket 连接监听,成功连接后再创建RPC服务
56
+ socket.on('connect', () => {
57
+ this.logger.log('PtyServiceManagerRemote connected');
58
+ rpcServiceDisposable === null || rpcServiceDisposable === void 0 ? void 0 : rpcServiceDisposable.dispose();
59
+ rpcServiceDisposable = this.initRPCService(socket);
60
+ });
61
+ // UNIX Socket 连接失败或者断开,此时需要等待 1.5s 后重新连接
62
+ socket.on('close', () => {
63
+ this.logger.log('PtyServiceManagerRemote connect failed, will reconnect after 2s');
64
+ rpcServiceDisposable === null || rpcServiceDisposable === void 0 ? void 0 : rpcServiceDisposable.dispose();
65
+ global.setTimeout(() => {
66
+ try {
67
+ socket.connect(connectOpts);
68
+ }
69
+ catch (e) {
70
+ this.logger.warn(e);
71
+ }
72
+ }, 2000);
73
+ });
74
+ try {
75
+ socket.connect(connectOpts);
76
+ }
77
+ catch (e) {
78
+ // 连接错误的时候会抛出异常,此时自动重连,同时需要 catch 错误
79
+ this.logger.warn(e);
80
+ }
81
+ }
82
+ initLocal() {
83
+ // override 空置父类的方法,因为不需要LocalInit,使用RemoteInit替代
84
+ }
85
+ };
86
+ PtyServiceManagerRemote = tslib_1.__decorate([
87
+ (0, di_1.Injectable)(),
88
+ tslib_1.__param(0, (0, di_1.Optional)()),
89
+ tslib_1.__metadata("design:paramtypes", [Object])
90
+ ], PtyServiceManagerRemote);
91
+ exports.PtyServiceManagerRemote = PtyServiceManagerRemote;
92
+ //# sourceMappingURL=pty.manager.remote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty.manager.remote.js","sourceRoot":"","sources":["../../src/node/pty.manager.remote.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /// <reference types="node" />
2
+ import { ListenOptions } from 'net';
3
+ import * as pty from 'node-pty';
4
+ import { IPtyProxyRPCService } from '../common';
5
+ /**
6
+ * NOTE: 这里面的Session通常是短Session 也就是OpenSumi里面Session `${clientId}|${sessionId}` 的sessionId部分
7
+ * 因为ClientId在每次刷新都会变化,而SessionId可以被持久化保存,后续按照之前的SessionID连接Pty的时候就可以做到Terminal Resume
8
+ *
9
+ * PtyServiceProxy是真实运行的托管着NodePty的代理
10
+ */
11
+ export declare class PtyServiceProxy implements IPtyProxyRPCService {
12
+ private ptyInstanceMap;
13
+ private ptyDataCacheMap;
14
+ private ptySessionMap;
15
+ private ptyDisposableMap;
16
+ private readonly debugLogger;
17
+ private $callback;
18
+ constructor(callback: (callId: number, ...args: any[]) => void);
19
+ private checkProcess;
20
+ $checkSession(sessionId: string): boolean;
21
+ $spawn(file: string, args: string[] | string, options: pty.IPtyForkOptions | pty.IWindowsPtyForkOptions, longSessionId?: string): any;
22
+ $onData(callId: number, pid: number): void;
23
+ $onExit(callId: number, pid: number): void;
24
+ $on(callId: number, pid: number, event: any): void;
25
+ $resize(pid: number, columns: number, rows: number): void;
26
+ $write(pid: number, data: string): void;
27
+ $kill(pid: number, signal?: string): void;
28
+ $pause(pid: number): void;
29
+ $resume(pid: number): void;
30
+ $getProcess(pid: number): string;
31
+ }
32
+ export declare class PtyServiceProxyRPCProvider {
33
+ private ptyServiceProxy;
34
+ private readonly ptyServiceCenter;
35
+ private readonly debugLogger;
36
+ private serverListenOptions;
37
+ private server;
38
+ constructor(listenOptions?: ListenOptions);
39
+ initServer(): void;
40
+ private createSocket;
41
+ private bindProcessHandler;
42
+ private setProxyConnection;
43
+ get $ptyServiceProxy(): PtyServiceProxy;
44
+ }
45
+ //# sourceMappingURL=pty.proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pty.proxy.d.ts","sourceRoot":"","sources":["../../src/node/pty.proxy.ts"],"names":[],"mappings":";AAEA,OAAY,EAAE,aAAa,EAAU,MAAM,KAAK,CAAC;AAEjD,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAMhC,OAAO,EACL,mBAAmB,EAKpB,MAAM,WAAW,CAAC;AAgCnB;;;;;GAKG;AACH,qBAAa,eAAgB,YAAW,mBAAmB;IAEzD,OAAO,CAAC,cAAc,CAA4B;IAElD,OAAO,CAAC,eAAe,CAAoC;IAE3D,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,gBAAgB,CAAwC;IAEhE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAqC;IACjE,OAAO,CAAC,SAAS,CAA+C;gBAEpD,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,OAAA,KAAK,IAAI;IAKvD,OAAO,CAAC,YAAY;IASpB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IASzC,MAAM,CACJ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,EACvB,OAAO,EAAE,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,sBAAsB,EACzD,aAAa,CAAC,EAAE,MAAM,GACrB,GAAG;IA6DN,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAwB1C,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAW1C,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI;IAOlD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKzD,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAMvC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAQzC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKzB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK1B,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAIjC;AAGD,qBAAa,0BAA0B;IACrC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAmB;IACpD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,mBAAmB,CAAgB;IAC3C,OAAO,CAAC,MAAM,CAAS;gBAEX,aAAa,GAAE,aAAuD;IAY3E,UAAU;IAKjB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,kBAAkB;IAQ1B,IAAW,gBAAgB,IAAI,eAAe,CAE7C;CACF"}
@@ -0,0 +1,255 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PtyServiceProxyRPCProvider = exports.PtyServiceProxy = void 0;
4
+ const tslib_1 = require("tslib");
5
+ /* eslint-disable no-console */
6
+ const fs_1 = tslib_1.__importDefault(require("fs"));
7
+ const net_1 = tslib_1.__importDefault(require("net"));
8
+ const pty = tslib_1.__importStar(require("node-pty"));
9
+ const ide_connection_1 = require("@opensumi/ide-connection");
10
+ const node_1 = require("@opensumi/ide-connection/lib/node");
11
+ const ide_core_node_1 = require("@opensumi/ide-core-node");
12
+ const common_1 = require("../common");
13
+ // 存储Pty-onData返回的数据行,用于用户Resume场景下的数据恢复
14
+ class PtyLineDataCache {
15
+ constructor(size = 100) {
16
+ this.dataArray = [];
17
+ this.size = size;
18
+ }
19
+ get data() {
20
+ return this.dataArray;
21
+ }
22
+ add(data) {
23
+ if (this.dataArray.length >= this.size) {
24
+ this.dataArray.shift();
25
+ }
26
+ this.dataArray.push(data);
27
+ }
28
+ clear() {
29
+ this.dataArray = [];
30
+ }
31
+ }
32
+ /**
33
+ * NOTE: 这里面的Session通常是短Session 也就是OpenSumi里面Session `${clientId}|${sessionId}` 的sessionId部分
34
+ * 因为ClientId在每次刷新都会变化,而SessionId可以被持久化保存,后续按照之前的SessionID连接Pty的时候就可以做到Terminal Resume
35
+ *
36
+ * PtyServiceProxy是真实运行的托管着NodePty的代理
37
+ */
38
+ class PtyServiceProxy {
39
+ constructor(callback) {
40
+ // Map <pid, pty> 存放进程Pid和Pty实例的映射
41
+ this.ptyInstanceMap = new Map();
42
+ // 存放Pid和对应Pty产生数据的记录
43
+ this.ptyDataCacheMap = new Map();
44
+ // 存放Session和Pid的映射
45
+ this.ptySessionMap = new Map();
46
+ this.ptyDisposableMap = new Map();
47
+ this.debugLogger = (0, ide_core_node_1.getDebugLogger)('PtyServiceProxy');
48
+ this.$callback = () => { };
49
+ this.$callback = callback;
50
+ }
51
+ // 检查Pty的PID是否存活
52
+ checkProcess(pid) {
53
+ try {
54
+ process.kill(pid, 0);
55
+ return true;
56
+ }
57
+ catch (e) {
58
+ return false;
59
+ }
60
+ }
61
+ $checkSession(sessionId) {
62
+ const pid = this.ptySessionMap.get(sessionId);
63
+ if (pid) {
64
+ return this.checkProcess(pid);
65
+ }
66
+ else {
67
+ return false;
68
+ }
69
+ }
70
+ $spawn(file, args, options, longSessionId) {
71
+ var _a, _b;
72
+ // 切割sessionId到短Id
73
+ const sessionId = (_a = longSessionId === null || longSessionId === void 0 ? void 0 : longSessionId.split(common_1.TERMINAL_ID_SEPARATOR)) === null || _a === void 0 ? void 0 : _a[1];
74
+ this.debugLogger.log('ptyServiceProxy: spawn sessionId:', sessionId);
75
+ let ptyInstance;
76
+ if (sessionId) {
77
+ // 查询SessionId对应的Pid
78
+ const pid = this.ptySessionMap.get(sessionId) || -10;
79
+ // 查询Pid是否存活
80
+ const checkResult = pid > 0 ? this.checkProcess(pid) : false;
81
+ this.debugLogger.debug('ptyServiceProxy: check process result:', pid, checkResult);
82
+ if (checkResult) {
83
+ ptyInstance = this.ptyInstanceMap.get(pid);
84
+ }
85
+ else {
86
+ // 有Session ID 但是没有 Process,说明是被系统杀了,此时需要重新spawn一个Pty
87
+ this.ptyInstanceMap.delete(pid);
88
+ ptyInstance = pty.spawn(file, args, options);
89
+ // 这种情况下,需要把之前的PtyCache给attach上去,方便用户查看记录
90
+ const oldLineCache = this.ptyDataCacheMap.get(pid);
91
+ if (oldLineCache) {
92
+ this.ptyDataCacheMap.set(ptyInstance.pid, oldLineCache);
93
+ this.ptyDataCacheMap.delete(pid);
94
+ }
95
+ }
96
+ }
97
+ // 如果不存在ptyInstance的话,则重新创建一个,兜底用,理论上不会走到这里
98
+ if (!ptyInstance) {
99
+ ptyInstance = pty.spawn(file, args, options);
100
+ }
101
+ this.ptyInstanceMap.set(ptyInstance.pid, ptyInstance);
102
+ if (sessionId) {
103
+ this.ptySessionMap.set(sessionId, ptyInstance.pid);
104
+ }
105
+ const pid = ptyInstance.pid;
106
+ // 初始化PtyLineCache
107
+ if (!this.ptyDataCacheMap.has(pid)) {
108
+ this.ptyDataCacheMap.set(pid, new PtyLineDataCache());
109
+ }
110
+ // 初始化ptyDisposableMap
111
+ if (!this.ptyDisposableMap.has(pid)) {
112
+ this.ptyDisposableMap.set(pid, new ide_core_node_1.DisposableCollection());
113
+ }
114
+ else {
115
+ // 如果已经存在DisposableCollection说明之前已经注册过,此时就需要取消注册,因为一会还要注册一遍
116
+ (_b = this.ptyDisposableMap.get(pid)) === null || _b === void 0 ? void 0 : _b.dispose();
117
+ }
118
+ // 走RPC序列化的部分,function不走序列化,走单独的RPC调用
119
+ const ptyInstanceSimple = {
120
+ pid: ptyInstance.pid,
121
+ cols: ptyInstance.cols,
122
+ rows: ptyInstance.rows,
123
+ process: ptyInstance.process,
124
+ handleFlowControl: ptyInstance.handleFlowControl,
125
+ };
126
+ this.debugLogger.log('ptyServiceProxy: spawn', ptyInstanceSimple);
127
+ return ptyInstanceSimple;
128
+ }
129
+ $onData(callId, pid) {
130
+ var _a;
131
+ this.debugLogger.debug('ptyServiceCenter $onData: callId: ', callId, ' pid: ', pid);
132
+ const ptyInstance = this.ptyInstanceMap.get(pid);
133
+ const cache = this.ptyDataCacheMap.get(pid);
134
+ cache === null || cache === void 0 ? void 0 : cache.data.forEach((value) => {
135
+ this.$callback(callId, value);
136
+ });
137
+ const onDataDisposable = ptyInstance === null || ptyInstance === void 0 ? void 0 : ptyInstance.onData((e) => {
138
+ this.debugLogger.debug('ptyServiceCenter: onData', JSON.stringify(e), 'pid:', pid, 'callId', callId);
139
+ if (typeof e === 'string') {
140
+ // 缓存数据的时候只存放前1024个字符,因为正常情况下也不会超过1024个,如果超过的话,基本上是用户误操作导致的cat 二进制文件或者其他未知问题
141
+ // 比如说某个程序一直通过CSI转义命令来以用户不可见的方式增加终端输出内容
142
+ // 缓存限制在每行1024字符来避免潜在的内存泄漏问题
143
+ cache === null || cache === void 0 ? void 0 : cache.add(e.slice(0, 1024));
144
+ }
145
+ this.$callback(callId, e);
146
+ });
147
+ if (onDataDisposable) {
148
+ (_a = this.ptyDisposableMap.get(pid)) === null || _a === void 0 ? void 0 : _a.push(onDataDisposable);
149
+ }
150
+ }
151
+ $onExit(callId, pid) {
152
+ var _a;
153
+ const ptyInstance = this.ptyInstanceMap.get(pid);
154
+ const onExitDisposable = ptyInstance === null || ptyInstance === void 0 ? void 0 : ptyInstance.onExit((e) => {
155
+ this.debugLogger.debug('ptyServiceCenter: onExit', 'pid:', pid, e);
156
+ this.$callback(callId, e);
157
+ });
158
+ if (onExitDisposable) {
159
+ (_a = this.ptyDisposableMap.get(pid)) === null || _a === void 0 ? void 0 : _a.push(onExitDisposable);
160
+ }
161
+ }
162
+ $on(callId, pid, event) {
163
+ const ptyInstance = this.ptyInstanceMap.get(pid);
164
+ ptyInstance === null || ptyInstance === void 0 ? void 0 : ptyInstance.on(event, (e) => {
165
+ this.$callback(callId, e);
166
+ });
167
+ }
168
+ $resize(pid, columns, rows) {
169
+ const ptyInstance = this.ptyInstanceMap.get(pid);
170
+ ptyInstance === null || ptyInstance === void 0 ? void 0 : ptyInstance.resize(columns, rows);
171
+ }
172
+ $write(pid, data) {
173
+ const ptyInstance = this.ptyInstanceMap.get(pid);
174
+ this.debugLogger.debug('ptyServiceCenter: write', JSON.stringify(data), 'pid:', pid);
175
+ ptyInstance === null || ptyInstance === void 0 ? void 0 : ptyInstance.write(data);
176
+ }
177
+ $kill(pid, signal) {
178
+ this.debugLogger.debug('ptyServiceCenter: kill', 'pid:', pid);
179
+ const ptyInstance = this.ptyInstanceMap.get(pid);
180
+ ptyInstance === null || ptyInstance === void 0 ? void 0 : ptyInstance.kill(signal);
181
+ this.ptyInstanceMap.delete(pid);
182
+ this.ptyDataCacheMap.delete(pid);
183
+ }
184
+ $pause(pid) {
185
+ const ptyInstance = this.ptyInstanceMap.get(pid);
186
+ ptyInstance === null || ptyInstance === void 0 ? void 0 : ptyInstance.pause();
187
+ }
188
+ $resume(pid) {
189
+ const ptyInstance = this.ptyInstanceMap.get(pid);
190
+ ptyInstance === null || ptyInstance === void 0 ? void 0 : ptyInstance.resume();
191
+ }
192
+ $getProcess(pid) {
193
+ const ptyInstance = this.ptyInstanceMap.get(pid);
194
+ return (ptyInstance === null || ptyInstance === void 0 ? void 0 : ptyInstance.process) || '';
195
+ }
196
+ }
197
+ exports.PtyServiceProxy = PtyServiceProxy;
198
+ // 需要单独运行PtyServer的时候集成此Class然后运行initServer
199
+ class PtyServiceProxyRPCProvider {
200
+ constructor(listenOptions = { port: common_1.PTY_SERVICE_PROXY_SERVER_PORT }) {
201
+ this.debugLogger = (0, ide_core_node_1.getDebugLogger)();
202
+ this.serverListenOptions = listenOptions;
203
+ this.ptyServiceCenter = new ide_connection_1.RPCServiceCenter();
204
+ const { createRPCService, getRPCService } = (0, ide_connection_1.initRPCService)(this.ptyServiceCenter);
205
+ const $callback = getRPCService(common_1.PTY_SERVICE_PROXY_CALLBACK_PROTOCOL)
206
+ .$callback;
207
+ this.ptyServiceProxy = new PtyServiceProxy($callback);
208
+ createRPCService(common_1.PTY_SERVICE_PROXY_PROTOCOL, this.ptyServiceProxy);
209
+ }
210
+ initServer() {
211
+ this.createSocket();
212
+ this.bindProcessHandler();
213
+ }
214
+ createSocket() {
215
+ this.server = net_1.default.createServer();
216
+ this.server.on('connection', (connection) => {
217
+ this.debugLogger.log('ptyServiceCenter: new connections coming in');
218
+ this.setProxyConnection(connection);
219
+ });
220
+ // const ipcPath = normalizedIpcHandlerPath()
221
+ if (this.serverListenOptions.path && fs_1.default.existsSync(this.serverListenOptions.path)) {
222
+ // UNIX DOMAIN SOCKET
223
+ fs_1.default.unlinkSync(this.serverListenOptions.path); // 兜底逻辑,如果之前Server没有清除掉SOCK文件的话,那就先清除
224
+ }
225
+ this.server.listen(this.serverListenOptions);
226
+ this.debugLogger.log('ptyServiceCenter: listening on', this.serverListenOptions);
227
+ }
228
+ // Close Server, release UNIX DOMAIN SOCKET
229
+ bindProcessHandler() {
230
+ // Handles normal process termination.
231
+ process.on('exit', () => {
232
+ this.server.close();
233
+ });
234
+ // Handles `Ctrl+C`.
235
+ process.on('SIGINT', async () => {
236
+ process.exit(0);
237
+ });
238
+ // Handles `kill pid`.
239
+ process.on('SIGTERM', async () => {
240
+ process.exit(0);
241
+ });
242
+ }
243
+ setProxyConnection(connection) {
244
+ const serverConnection = (0, node_1.createSocketConnection)(connection);
245
+ this.ptyServiceCenter.setConnection(serverConnection);
246
+ connection.on('close', () => {
247
+ this.ptyServiceCenter.removeConnection(serverConnection);
248
+ });
249
+ }
250
+ get $ptyServiceProxy() {
251
+ return this.ptyServiceProxy;
252
+ }
253
+ }
254
+ exports.PtyServiceProxyRPCProvider = PtyServiceProxyRPCProvider;
255
+ //# sourceMappingURL=pty.proxy.js.map