bdy 1.23.9-dev → 1.23.10-dev

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bdy",
3
3
  "preferGlobal": false,
4
- "version": "1.23.9-dev",
4
+ "version": "1.23.10-dev",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
7
7
  "homepage": "https://buddy.works/docs/cli",
@@ -139,6 +139,7 @@ class Agent extends events_1.default {
139
139
  try {
140
140
  if (data.agent.action)
141
141
  await this.makeAction(data.agent.action);
142
+ this.reclearLostUpdateStatus(data.agent.action);
142
143
  const filtered = (data.tunnels || []).filter((t) => !!t.domain);
143
144
  this.refreshTunnels(filtered);
144
145
  }
@@ -290,12 +291,50 @@ class Agent extends events_1.default {
290
291
  return;
291
292
  this.updateStatusExpiry = setTimeout(() => {
292
293
  this.updateStatusExpiry = null;
293
- this.ackAction();
294
+ this.queueUpdateStatusClear();
294
295
  }, utils_1.AGENT_UPDATE_STATUS_TTL_MS);
295
296
  // A foreground tunnel reporting UNSUPPORTED exits as soon as it has acked, and must
296
297
  // not be held open for the rest of the window just to tidy up after itself
297
298
  this.updateStatusExpiry.unref();
298
299
  }
300
+ // Queued rather than sent, because a fetch of our own here would go out within
301
+ // milliseconds of refreshIn15's tick: this expiry and that interval are both armed when
302
+ // the process starts, and the ttl is a multiple of the interval. The backend writes the
303
+ // whole agent row per request, so the tick - which carries no action at all - rewrites
304
+ // the field this clear just emptied, and the outcome is back with nobody left to remove
305
+ // it. Riding the next scheduled fetch keeps it to one write per tick.
306
+ queueUpdateStatusClear() {
307
+ if (!this.socket)
308
+ return;
309
+ // An outcome reported in the meantime is the newer truth and has a window of its own
310
+ if (this.socket.pendingAction !== null)
311
+ return;
312
+ this.socket.setPendingAction('');
313
+ }
314
+ // An outcome still on the record after its window is one whose clear did not survive -
315
+ // see queueUpdateStatusClear for how that happens, and note it can equally be a status
316
+ // left behind by a process that died before its expiry ever fired. Either way nothing
317
+ // dates the value, so it would sit there until the next update request: queue the clear
318
+ // again and let the fetch after this one carry it.
319
+ reclearLostUpdateStatus(action) {
320
+ if (typeof action !== 'string')
321
+ return;
322
+ const statuses = Object.values(tunnel_1.TUNNEL_AGENT_UPDATE_STATUS);
323
+ if (!statuses.includes(action))
324
+ return;
325
+ // Never an outcome, and the one value the front reads as an unknown result
326
+ if (action === tunnel_1.TUNNEL_AGENT_UPDATE_STATUS.STARTED)
327
+ return;
328
+ // Still inside the window this status is being shown for
329
+ if (this.updateStatusExpiry)
330
+ return;
331
+ this.queueUpdateStatusClear();
332
+ // Sent from here rather than left for the next scheduled fetch, unlike the expiry above:
333
+ // this runs on a fetch response, which is as far from the next refresh tick as the
334
+ // schedule ever gets, so there is nothing to collide with. Waiting for two more fetches
335
+ // would leave a confirmation standing for a minute and a half.
336
+ this.ackAction();
337
+ }
299
338
  // For a status with no ack to ride on - STARTED, reported while the download is still
300
339
  // running. Passes null so that if the status has somehow already gone out, this does
301
340
  // not overwrite it with an empty action.
@@ -178,6 +178,8 @@ commandSandboxCreate.action(async (options) => {
178
178
  output_1.default.cyan(result.identifier);
179
179
  output_1.default.dim('SSH: ', false);
180
180
  output_1.default.cyan(`ssh ${result.ssh_host} -p ${result.ssh_port}`);
181
+ output_1.default.dim('SSH via CLI: ', false);
182
+ output_1.default.cyan(`bdy sb ssh ${result.identifier}`);
181
183
  output_1.default.dim('Web terminal: ', false);
182
184
  output_1.default.cyan(result.html_url);
183
185
  output_1.default.green(texts_1.TXT_SANDBOX_CREATED);
@@ -44,6 +44,7 @@ commandSandboxGet.action(async (identifier, options) => {
44
44
  ? `ssh ${sandbox.ssh_host} -p ${sandbox.ssh_port}`
45
45
  : '-',
46
46
  ],
47
+ ['SSH via CLI', sandbox.identifier ? `bdy sb ssh ${sandbox.identifier}` : '-']
47
48
  ];
48
49
  if (sandbox.endpoints && sandbox.endpoints.length > 0) {
49
50
  data.push([
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bdy",
3
3
  "preferGlobal": false,
4
- "version": "1.23.9-dev",
4
+ "version": "1.23.10-dev",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
7
7
  "homepage": "https://buddy.works/docs/cli",