pterm 0.0.24 → 0.0.25

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/rpc.js CHANGED
@@ -21,7 +21,16 @@ class RPC {
21
21
  return res
22
22
  }
23
23
  close() {
24
- this.ws.close()
24
+ if (!this.ws) {
25
+ return
26
+ }
27
+ const ws = this.ws
28
+ delete this.ws
29
+ if (typeof ws.terminate === 'function') {
30
+ ws.terminate()
31
+ return
32
+ }
33
+ ws.close()
25
34
  }
26
35
  stop(rpc) {
27
36
  this.run({
@@ -43,23 +52,32 @@ class RPC {
43
52
  if (this.ws) {
44
53
  this.ws.send(JSON.stringify(rpc))
45
54
  } else {
46
- this.ws = new WebSocket(this.url, this.wsOptions)
47
- this.ws.addEventListener('open', () => {
48
- this.ws.send(JSON.stringify(rpc))
55
+ const ws = new WebSocket(this.url, this.wsOptions)
56
+ this.ws = ws
57
+ ws.addEventListener('open', () => {
58
+ ws.send(JSON.stringify(rpc))
49
59
  });
50
- this.ws.addEventListener('message', (message) => {
60
+ ws.addEventListener('message', (message) => {
51
61
  /******************************************************************************
52
62
 
53
63
 
54
64
  ******************************************************************************/
55
65
  if (ondata) {
56
- const packet = JSON.parse(message.data);
66
+ const rawMessage = message && typeof message === 'object' && typeof message.data !== 'undefined'
67
+ ? message.data
68
+ : message
69
+ const packetSource = Buffer.isBuffer(rawMessage)
70
+ ? rawMessage.toString('utf8')
71
+ : String(rawMessage)
72
+ const packet = JSON.parse(packetSource);
57
73
  ondata(packet)
58
74
  }
59
75
  });
60
- this.ws.addEventListener('close', () => {
76
+ ws.addEventListener('close', () => {
61
77
  // console.log('Disconnected from WebSocket endpoint', { error: this.error, result: this.result });
62
- delete this.ws
78
+ if (this.ws === ws) {
79
+ delete this.ws
80
+ }
63
81
  resolve()
64
82
  });
65
83
  }
package/script.js CHANGED
@@ -1,5 +1,8 @@
1
+ const os = require('os')
1
2
  const path = require('path')
2
3
  const RPC = require('./rpc')
4
+ const { resolveWsBaseUrl } = require('./endpoint')
5
+ const { resolveAppControlTarget, resolveStopTarget } = require('./target')
3
6
  class Script {
4
7
  listen(onKey) {
5
8
  if (process.stdin.isTTY) {
@@ -42,33 +45,46 @@ class Script {
42
45
  input[key] = value
43
46
  }
44
47
  }
45
- if (target && typeof target === "object" && typeof target.uri === "string") {
48
+ const parseTargetUri = (rawUri) => {
49
+ let uri = rawUri
50
+ let input
51
+ if (!/^https?:\/\//i.test(uri)) {
52
+ let queryIndex = uri.indexOf("?")
53
+ if (queryIndex >= 0) {
54
+ input = {}
55
+ let params = new URLSearchParams(uri.slice(queryIndex + 1))
56
+ for (let [key, value] of params.entries()) {
57
+ appendInputValue(input, key, value)
58
+ }
59
+ uri = uri.slice(0, queryIndex)
60
+ }
61
+ if (uri.startsWith('~/')) {
62
+ uri = path.resolve(os.homedir(), uri.slice(2))
63
+ } else {
64
+ uri = path.resolve(process.cwd(), uri)
65
+ }
66
+ }
46
67
  return {
47
- uri: target.uri,
48
- input: target.input && typeof target.input === "object" ? target.input : undefined
68
+ uri,
69
+ input
49
70
  }
50
71
  }
51
- let uri = target
52
- let input
53
- if (!/^https?:\/\//i.test(uri)) {
54
- let queryIndex = uri.indexOf("?")
55
- if (queryIndex >= 0) {
56
- input = {}
57
- let params = new URLSearchParams(uri.slice(queryIndex + 1))
58
- for (let [key, value] of params.entries()) {
59
- appendInputValue(input, key, value)
60
- }
61
- uri = uri.slice(0, queryIndex)
72
+ if (target && typeof target === "object" && typeof target.uri === "string") {
73
+ const normalized = parseTargetUri(target.uri)
74
+ return {
75
+ uri: normalized.uri,
76
+ input: normalized.input
77
+ ? {
78
+ ...(target.input && typeof target.input === "object" ? target.input : {}),
79
+ ...normalized.input
80
+ }
81
+ : (target.input && typeof target.input === "object" ? target.input : undefined)
62
82
  }
63
- uri = path.resolve(process.cwd(), uri)
64
- }
65
- return {
66
- uri,
67
- input
68
83
  }
84
+ return parseTargetUri(target)
69
85
  }
70
- async default_script (uri, defaultSelectors) {
71
- const rpc = new RPC("ws://localhost:42000")
86
+ async default_script (uri, defaultSelectors, targetControlPlane) {
87
+ const rpc = new RPC(await resolveWsBaseUrl(targetControlPlane))
72
88
  const stop = () => {
73
89
  rpc.run({
74
90
  method: "kernel.api.stop",
@@ -98,14 +114,17 @@ class Script {
98
114
  source: "pterm"
99
115
  }
100
116
  }, (packet) => {
101
- if (packet.data && packet.data.uri) {
102
- // start
103
- //rpc.stop({ uri })
104
- stop()
105
- resolve({
106
- uri: packet.data.uri,
107
- input: packet.data.input
108
- })
117
+ if (packet && packet.data) {
118
+ rpc.close()
119
+ if (packet.data.uri) {
120
+ stop()
121
+ resolve({
122
+ uri: packet.data.uri,
123
+ input: packet.data.input
124
+ })
125
+ } else {
126
+ resolve(null)
127
+ }
109
128
  }
110
129
  })
111
130
  })
@@ -114,22 +133,42 @@ class Script {
114
133
  async stop(argv) {
115
134
  if (argv._.length > 1) {
116
135
  let _uri = argv._[1]
117
- const { uri } = this.normalizeTarget(_uri)
118
- const rpc = new RPC("ws://localhost:42000")
119
- rpc.run({
120
- method: "kernel.api.stop",
121
- params: { uri }
122
- }, (packet) => {
123
- process.exit()
124
- })
136
+ const target = await resolveStopTarget(_uri, argv.ref)
137
+ if (!target.uris.length) {
138
+ process.exit(0)
139
+ return
140
+ }
141
+ for (const uri of target.uris) {
142
+ const rpc = new RPC(await resolveWsBaseUrl(target.controlPlane))
143
+ await new Promise((resolve) => {
144
+ let settled = false
145
+ const finish = () => {
146
+ if (settled) {
147
+ return
148
+ }
149
+ settled = true
150
+ rpc.close()
151
+ resolve()
152
+ }
153
+ const timer = setTimeout(finish, 800)
154
+ rpc.run({
155
+ method: "kernel.api.stop",
156
+ params: { uri }
157
+ }, () => {
158
+ clearTimeout(timer)
159
+ finish()
160
+ })
161
+ })
162
+ }
163
+ process.exit(0)
125
164
  } else {
126
165
  console.error("required argument: <uri>")
127
166
  }
128
167
  }
129
- async start(_uri, kill, ondata) {
168
+ async start(_uri, kill, ondata, targetControlPlane) {
130
169
  const cols = process.stdout.columns;
131
170
  const rows = process.stdout.rows;
132
- const rpc = new RPC("ws://localhost:42000")
171
+ const rpc = new RPC(await resolveWsBaseUrl(targetControlPlane))
133
172
 
134
173
  const target = this.normalizeTarget(_uri)
135
174
  const uri = target.uri
@@ -143,18 +182,22 @@ class Script {
143
182
  rpc.stop({ uri })
144
183
  })
145
184
  }
146
- process.on("SIGINT", () => {
185
+ const onSigInt = () => {
147
186
  stop()
148
- });
149
- process.on("SIGTERM", () => {
187
+ }
188
+ const onSigTerm = () => {
150
189
  stop()
151
- });
152
- process.on("beforeExit", (code) => {
190
+ }
191
+ const onBeforeExit = () => {
153
192
  stop()
154
- });
155
- process.on("exit", (code) => {
193
+ }
194
+ const onExit = () => {
156
195
  stop()
157
- });
196
+ }
197
+ process.on("SIGINT", onSigInt);
198
+ process.on("SIGTERM", onSigTerm);
199
+ process.on("beforeExit", onBeforeExit);
200
+ process.on("exit", onExit);
158
201
  this.key_stop = this.listen((key) => {
159
202
  if (key.length >= 256) {
160
203
  rpc.run({
@@ -169,7 +212,7 @@ class Script {
169
212
  })
170
213
  }
171
214
  });
172
- process.stdout.on('resize', () => {
215
+ const resizeHandler = () => {
173
216
  const cols = process.stdout.columns;
174
217
  const rows = process.stdout.rows;
175
218
  rpc.run({
@@ -180,7 +223,8 @@ class Script {
180
223
  }
181
224
  }, (packet) => {
182
225
  })
183
- });
226
+ }
227
+ process.stdout.on('resize', resizeHandler);
184
228
  let payload = {
185
229
  uri,
186
230
  source: "pterm",
@@ -193,19 +237,30 @@ class Script {
193
237
  if (target.input && Object.keys(target.input).length > 0) {
194
238
  payload.input = target.input
195
239
  }
240
+ let cleanedUp = false
241
+ const cleanupLocalSession = () => {
242
+ if (cleanedUp) {
243
+ return
244
+ }
245
+ cleanedUp = true
246
+ if (this.key_stop) {
247
+ this.key_stop()
248
+ this.key_stop = null
249
+ }
250
+ process.stdout.off('resize', resizeHandler)
251
+ process.off("SIGINT", onSigInt)
252
+ process.off("SIGTERM", onSigTerm)
253
+ process.off("beforeExit", onBeforeExit)
254
+ process.off("exit", onExit)
255
+ rpc.close()
256
+ }
196
257
  await rpc.run(payload, (packet) => {
197
258
  if (packet.type === "stop") {
198
- rpc.stop({ uri })
199
- if (kill) {
200
- this.key_stop()
201
- process.exit()
202
- }
259
+ cleanupLocalSession()
260
+ process.exit(0)
203
261
  } else if (packet.type === "disconnect") {
204
- rpc.close()
205
- if (kill) {
206
- this.key_stop()
207
- process.exit()
208
- }
262
+ cleanupLocalSession()
263
+ process.exit(0)
209
264
  } else if (packet.type === "stream") {
210
265
  if (packet.data.id) {
211
266
  this.shell_id = packet.data.id