@mindexec/cli 0.2.139 → 0.2.140

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindexec/cli",
3
- "version": "0.2.139",
3
+ "version": "0.2.140",
4
4
  "description": "MindExec local runtime and bridge CLI",
5
5
  "main": "server.js",
6
6
  "type": "module",
@@ -419,6 +419,10 @@ async function loadCss3DManager() {
419
419
  const objectUrlCalls = [];
420
420
  const revokedObjectUrls = [];
421
421
  const imageBitmapCalls = [];
422
+ const fetchCalls = [];
423
+ const runtimeTrace = [];
424
+ const webSocketConnections = [];
425
+ const webSocketSends = [];
422
426
  class SmokeURL extends URL {}
423
427
  SmokeURL.createObjectURL = blob => {
424
428
  objectUrlCalls.push(blob);
@@ -427,9 +431,43 @@ async function loadCss3DManager() {
427
431
  SmokeURL.revokeObjectURL = value => {
428
432
  revokedObjectUrls.push(String(value || ''));
429
433
  };
434
+ class MiniWebSocket {
435
+ static CONNECTING = 0;
436
+ static OPEN = 1;
437
+ static CLOSING = 2;
438
+ static CLOSED = 3;
439
+
440
+ constructor(url) {
441
+ this.url = String(url || '');
442
+ this.readyState = MiniWebSocket.CONNECTING;
443
+ this.binaryType = '';
444
+ this.sent = [];
445
+ webSocketConnections.push(this);
446
+ setTimeout(() => {
447
+ if (this.readyState !== MiniWebSocket.CONNECTING) return;
448
+ this.readyState = MiniWebSocket.OPEN;
449
+ this.onopen?.({ type: 'open' });
450
+ }, 0);
451
+ }
452
+
453
+ send(payload) {
454
+ const text = typeof payload === 'string' ? payload : String(payload || '');
455
+ this.sent.push(text);
456
+ webSocketSends.push({ url: this.url, payload: text });
457
+ }
458
+
459
+ close() {
460
+ if (this.readyState === MiniWebSocket.CLOSED) return;
461
+ this.readyState = MiniWebSocket.CLOSED;
462
+ this.onclose?.({ type: 'close' });
463
+ }
464
+ }
430
465
  const context = {
431
466
  console,
432
467
  document,
468
+ location: {
469
+ origin: 'http://localhost:5147'
470
+ },
433
471
  navigator: {
434
472
  clipboard: {
435
473
  writeText: async () => {}
@@ -466,6 +504,23 @@ async function loadCss3DManager() {
466
504
  },
467
505
  THREE: createThreeStub(),
468
506
  URL: SmokeURL,
507
+ WebSocket: MiniWebSocket,
508
+ fetch: async (url, options = {}) => {
509
+ fetchCalls.push({ url: String(url || ''), options });
510
+ return {
511
+ ok: true,
512
+ status: 200,
513
+ json: async () => ({
514
+ bridgeToken: 'render-smoke-bridge-token',
515
+ remoteFrameWsPath: '/api/remote/frames/ws'
516
+ })
517
+ };
518
+ },
519
+ RuntimeTrace: {
520
+ emit(type, data = {}) {
521
+ runtimeTrace.push({ type, ...data });
522
+ }
523
+ },
469
524
  Promise
470
525
  };
471
526
  context.window = context;
@@ -478,7 +533,11 @@ async function loadCss3DManager() {
478
533
  diagnostics: {
479
534
  objectUrlCalls,
480
535
  revokedObjectUrls,
481
- imageBitmapCalls
536
+ imageBitmapCalls,
537
+ fetchCalls,
538
+ runtimeTrace,
539
+ webSocketConnections,
540
+ webSocketSends
482
541
  }
483
542
  };
484
543
  }
@@ -530,6 +589,7 @@ function buildMonitorNode(devices, hubStatus, latestTaskBatch = null, recentTask
530
589
  function createRemoteFleetTemplateShell(document, focusDeviceId = '') {
531
590
  const nodeShell = document.createElement('div');
532
591
  nodeShell.setAttribute('class', 'map-node-template-card map-node-remote-fleet');
592
+ nodeShell.dataset.nodeId = 'remote-fleet-render-smoke';
533
593
  const shell = document.createElement('div');
534
594
  shell.setAttribute('class', 'template-card__shell template-card__shell--remote-fleet');
535
595
  const header = document.createElement('div');
@@ -542,7 +602,8 @@ function createRemoteFleetTemplateShell(document, focusDeviceId = '') {
542
602
  header.appendChild(icon);
543
603
  header.appendChild(titleWrap);
544
604
  const bodyView = document.createElement('div');
545
- bodyView.setAttribute('class', 'template-card__remote-fleet-body');
605
+ bodyView.setAttribute('class', 'template-card__remote-fleet-body map-node-remote-fleet__body');
606
+ bodyView.dataset.nodeId = 'remote-fleet-render-smoke';
546
607
  bodyView.dataset.remoteFleetAutoMonitor = 'false';
547
608
  if (focusDeviceId) {
548
609
  bodyView.dataset.remoteFleetFocusDeviceId = focusDeviceId;
@@ -939,9 +1000,31 @@ try {
939
1000
  const resultPanel = bodyView.querySelector('[data-remote-fleet-task-results="true"]');
940
1001
  assert.equal(resultPanel, null);
941
1002
  assert.ok(devices.some(device => /^synthetic-response-/.test(device.LatestTaskResultResponseId)));
942
- await wait();
1003
+ await wait(20);
943
1004
  const liveStartCalls = dotNetCalls.filter(call => call.methodName === 'StartRemoteFleetLiveStreamFromJs');
944
- assert.ok(liveStartCalls.length > 1, `expected multiple visible live starts, got ${liveStartCalls.length}`);
1005
+ const subscribeMessages = diagnostics.webSocketSends
1006
+ .map(send => {
1007
+ try {
1008
+ return JSON.parse(send.payload);
1009
+ } catch {
1010
+ return null;
1011
+ }
1012
+ })
1013
+ .filter(Boolean);
1014
+ const autoLiveSubscribe = subscribeMessages.find(message =>
1015
+ message.type === 'subscribe'
1016
+ && message.nodeId === 'remote-fleet-render-smoke'
1017
+ && message.autoStartLive === true);
1018
+ assert.ok(diagnostics.fetchCalls.some(call => call.url.includes('/api/status?remoteFrames=ws')));
1019
+ assert.ok(diagnostics.webSocketConnections.length >= 1, 'expected MDM render to open binary frame WebSocket');
1020
+ assert.ok(autoLiveSubscribe, 'expected MDM render to subscribe with autoStartLive over WebSocket');
1021
+ assert.equal(autoLiveSubscribe.fps, 12);
1022
+ assert.equal(autoLiveSubscribe.maxWidth, 960);
1023
+ assert.equal(autoLiveSubscribe.maxHeight, 540);
1024
+ assert.equal(autoLiveSubscribe.quality, 60);
1025
+ assert.ok(autoLiveSubscribe.deviceIds.length > 1, 'expected visible connected devices in WS subscription');
1026
+ assert.ok(diagnostics.runtimeTrace.some(event => event.type === 'remote.live.wsAutoStartRequested'));
1027
+ assert.equal(liveStartCalls.length, 0, 'WebSocket live path must not call DotNet live-start fallback');
945
1028
  await wait(320);
946
1029
  assert.ok(dotNetCalls.some(call => call.methodName === 'RefreshRemoteFleetMonitorNodeFromJs'));
947
1030
  assert.equal(bodyView.dataset.remoteFleetTaskFollowKey, 'render-smoke-batch');