@quenty/studio-bridge 0.7.1 → 0.8.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.
- package/CHANGELOG.md +12 -44
- package/README.md +166 -115
- package/dist/src/bridge/bridge-connection-remote.test.d.ts +7 -0
- package/dist/src/bridge/bridge-connection-remote.test.d.ts.map +1 -0
- package/dist/src/bridge/bridge-connection-remote.test.js +144 -0
- package/dist/src/bridge/bridge-connection-remote.test.js.map +1 -0
- package/dist/src/bridge/bridge-connection.d.ts +112 -0
- package/dist/src/bridge/bridge-connection.d.ts.map +1 -0
- package/dist/src/bridge/bridge-connection.js +528 -0
- package/dist/src/bridge/bridge-connection.js.map +1 -0
- package/dist/src/bridge/bridge-connection.test.d.ts +6 -0
- package/dist/src/bridge/bridge-connection.test.d.ts.map +1 -0
- package/dist/src/bridge/bridge-connection.test.js +773 -0
- package/dist/src/bridge/bridge-connection.test.js.map +1 -0
- package/dist/src/bridge/bridge-session.d.ts +38 -0
- package/dist/src/bridge/bridge-session.d.ts.map +1 -0
- package/dist/src/bridge/bridge-session.js +259 -0
- package/dist/src/bridge/bridge-session.js.map +1 -0
- package/dist/src/bridge/bridge-session.test.d.ts +6 -0
- package/dist/src/bridge/bridge-session.test.d.ts.map +1 -0
- package/dist/src/bridge/bridge-session.test.js +264 -0
- package/dist/src/bridge/bridge-session.test.js.map +1 -0
- package/dist/src/bridge/index.d.ts +13 -0
- package/dist/src/bridge/index.d.ts.map +1 -0
- package/dist/src/bridge/index.js +13 -0
- package/dist/src/bridge/index.js.map +1 -0
- package/dist/src/bridge/internal/__tests__/failover-crash.test.d.ts +9 -0
- package/dist/src/bridge/internal/__tests__/failover-crash.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/__tests__/failover-crash.test.js +159 -0
- package/dist/src/bridge/internal/__tests__/failover-crash.test.js.map +1 -0
- package/dist/src/bridge/internal/__tests__/failover-graceful.test.d.ts +9 -0
- package/dist/src/bridge/internal/__tests__/failover-graceful.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/__tests__/failover-graceful.test.js +218 -0
- package/dist/src/bridge/internal/__tests__/failover-graceful.test.js.map +1 -0
- package/dist/src/bridge/internal/__tests__/failover-inflight.test.d.ts +9 -0
- package/dist/src/bridge/internal/__tests__/failover-inflight.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/__tests__/failover-inflight.test.js +246 -0
- package/dist/src/bridge/internal/__tests__/failover-inflight.test.js.map +1 -0
- package/dist/src/bridge/internal/__tests__/host-client-integration.test.d.ts +10 -0
- package/dist/src/bridge/internal/__tests__/host-client-integration.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/__tests__/host-client-integration.test.js +298 -0
- package/dist/src/bridge/internal/__tests__/host-client-integration.test.js.map +1 -0
- package/dist/src/bridge/internal/bridge-client.d.ts +70 -0
- package/dist/src/bridge/internal/bridge-client.d.ts.map +1 -0
- package/dist/src/bridge/internal/bridge-client.js +344 -0
- package/dist/src/bridge/internal/bridge-client.js.map +1 -0
- package/dist/src/bridge/internal/bridge-client.test.d.ts +7 -0
- package/dist/src/bridge/internal/bridge-client.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/bridge-client.test.js +301 -0
- package/dist/src/bridge/internal/bridge-client.test.js.map +1 -0
- package/dist/src/bridge/internal/bridge-host.d.ts +78 -0
- package/dist/src/bridge/internal/bridge-host.d.ts.map +1 -0
- package/dist/src/bridge/internal/bridge-host.js +383 -0
- package/dist/src/bridge/internal/bridge-host.js.map +1 -0
- package/dist/src/bridge/internal/bridge-host.test.d.ts +7 -0
- package/dist/src/bridge/internal/bridge-host.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/bridge-host.test.js +377 -0
- package/dist/src/bridge/internal/bridge-host.test.js.map +1 -0
- package/dist/src/bridge/internal/environment-detection.d.ts +44 -0
- package/dist/src/bridge/internal/environment-detection.d.ts.map +1 -0
- package/dist/src/bridge/internal/environment-detection.js +91 -0
- package/dist/src/bridge/internal/environment-detection.js.map +1 -0
- package/dist/src/bridge/internal/environment-detection.test.d.ts +7 -0
- package/dist/src/bridge/internal/environment-detection.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/environment-detection.test.js +150 -0
- package/dist/src/bridge/internal/environment-detection.test.js.map +1 -0
- package/dist/src/bridge/internal/hand-off.d.ts +69 -0
- package/dist/src/bridge/internal/hand-off.d.ts.map +1 -0
- package/dist/src/bridge/internal/hand-off.js +178 -0
- package/dist/src/bridge/internal/hand-off.js.map +1 -0
- package/dist/src/bridge/internal/hand-off.test.d.ts +7 -0
- package/dist/src/bridge/internal/hand-off.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/hand-off.test.js +325 -0
- package/dist/src/bridge/internal/hand-off.test.js.map +1 -0
- package/dist/src/bridge/internal/health-endpoint.d.ts +32 -0
- package/dist/src/bridge/internal/health-endpoint.d.ts.map +1 -0
- package/dist/src/bridge/internal/health-endpoint.js +73 -0
- package/dist/src/bridge/internal/health-endpoint.js.map +1 -0
- package/dist/src/bridge/internal/health-endpoint.test.d.ts +6 -0
- package/dist/src/bridge/internal/health-endpoint.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/health-endpoint.test.js +122 -0
- package/dist/src/bridge/internal/health-endpoint.test.js.map +1 -0
- package/dist/src/bridge/internal/host-protocol.d.ts +60 -0
- package/dist/src/bridge/internal/host-protocol.d.ts.map +1 -0
- package/dist/src/bridge/internal/host-protocol.js +184 -0
- package/dist/src/bridge/internal/host-protocol.js.map +1 -0
- package/dist/src/bridge/internal/host-protocol.test.d.ts +6 -0
- package/dist/src/bridge/internal/host-protocol.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/host-protocol.test.js +307 -0
- package/dist/src/bridge/internal/host-protocol.test.js.map +1 -0
- package/dist/src/bridge/internal/session-tracker.d.ts +67 -0
- package/dist/src/bridge/internal/session-tracker.d.ts.map +1 -0
- package/dist/src/bridge/internal/session-tracker.js +138 -0
- package/dist/src/bridge/internal/session-tracker.js.map +1 -0
- package/dist/src/bridge/internal/session-tracker.test.d.ts +6 -0
- package/dist/src/bridge/internal/session-tracker.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/session-tracker.test.js +342 -0
- package/dist/src/bridge/internal/session-tracker.test.js.map +1 -0
- package/dist/src/bridge/internal/transport-client.d.ts +43 -0
- package/dist/src/bridge/internal/transport-client.d.ts.map +1 -0
- package/dist/src/bridge/internal/transport-client.js +146 -0
- package/dist/src/bridge/internal/transport-client.js.map +1 -0
- package/dist/src/bridge/internal/transport-client.test.d.ts +6 -0
- package/dist/src/bridge/internal/transport-client.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/transport-client.test.js +176 -0
- package/dist/src/bridge/internal/transport-client.test.js.map +1 -0
- package/dist/src/bridge/internal/transport-server.d.ts +59 -0
- package/dist/src/bridge/internal/transport-server.d.ts.map +1 -0
- package/dist/src/bridge/internal/transport-server.js +189 -0
- package/dist/src/bridge/internal/transport-server.js.map +1 -0
- package/dist/src/bridge/internal/transport-server.test.d.ts +6 -0
- package/dist/src/bridge/internal/transport-server.test.d.ts.map +1 -0
- package/dist/src/bridge/internal/transport-server.test.js +171 -0
- package/dist/src/bridge/internal/transport-server.test.js.map +1 -0
- package/dist/src/bridge/types.d.ts +117 -0
- package/dist/src/bridge/types.d.ts.map +1 -0
- package/dist/src/bridge/types.js +68 -0
- package/dist/src/bridge/types.js.map +1 -0
- package/dist/src/cli/adapters/cli-command-adapter-handler.test.d.ts +6 -0
- package/dist/src/cli/adapters/cli-command-adapter-handler.test.d.ts.map +1 -0
- package/dist/src/cli/adapters/cli-command-adapter-handler.test.js +260 -0
- package/dist/src/cli/adapters/cli-command-adapter-handler.test.js.map +1 -0
- package/dist/src/cli/adapters/cli-command-adapter.d.ts +39 -0
- package/dist/src/cli/adapters/cli-command-adapter.d.ts.map +1 -0
- package/dist/src/cli/adapters/cli-command-adapter.js +241 -0
- package/dist/src/cli/adapters/cli-command-adapter.js.map +1 -0
- package/dist/src/cli/adapters/cli-command-adapter.test.d.ts +5 -0
- package/dist/src/cli/adapters/cli-command-adapter.test.d.ts.map +1 -0
- package/dist/src/cli/adapters/cli-command-adapter.test.js +188 -0
- package/dist/src/cli/adapters/cli-command-adapter.test.js.map +1 -0
- package/dist/src/cli/adapters/group-builder.d.ts +29 -0
- package/dist/src/cli/adapters/group-builder.d.ts.map +1 -0
- package/dist/src/cli/adapters/group-builder.js +54 -0
- package/dist/src/cli/adapters/group-builder.js.map +1 -0
- package/dist/src/cli/adapters/group-builder.test.d.ts +5 -0
- package/dist/src/cli/adapters/group-builder.test.d.ts.map +1 -0
- package/dist/src/cli/adapters/group-builder.test.js +108 -0
- package/dist/src/cli/adapters/group-builder.test.js.map +1 -0
- package/dist/src/cli/adapters/help-formatter.d.ts +11 -0
- package/dist/src/cli/adapters/help-formatter.d.ts.map +1 -0
- package/dist/src/cli/adapters/help-formatter.js +78 -0
- package/dist/src/cli/adapters/help-formatter.js.map +1 -0
- package/dist/src/cli/adapters/help-formatter.test.d.ts +5 -0
- package/dist/src/cli/adapters/help-formatter.test.d.ts.map +1 -0
- package/dist/src/cli/adapters/help-formatter.test.js +79 -0
- package/dist/src/cli/adapters/help-formatter.test.js.map +1 -0
- package/dist/src/cli/adapters/target-resolver.d.ts +54 -0
- package/dist/src/cli/adapters/target-resolver.d.ts.map +1 -0
- package/dist/src/cli/adapters/target-resolver.js +90 -0
- package/dist/src/cli/adapters/target-resolver.js.map +1 -0
- package/dist/src/cli/adapters/target-resolver.test.d.ts +5 -0
- package/dist/src/cli/adapters/target-resolver.test.d.ts.map +1 -0
- package/dist/src/cli/adapters/target-resolver.test.js +169 -0
- package/dist/src/cli/adapters/target-resolver.test.js.map +1 -0
- package/dist/src/cli/args/global-args.d.ts +2 -0
- package/dist/src/cli/args/global-args.d.ts.map +1 -1
- package/dist/src/cli/cli.d.ts +6 -3
- package/dist/src/cli/cli.d.ts.map +1 -1
- package/dist/src/cli/cli.js +82 -20
- package/dist/src/cli/cli.js.map +1 -1
- package/dist/src/cli/resolve-script-content.d.ts +19 -0
- package/dist/src/cli/resolve-script-content.d.ts.map +1 -0
- package/dist/src/cli/resolve-script-content.js +22 -0
- package/dist/src/cli/resolve-script-content.js.map +1 -0
- package/dist/src/cli/resolve-session.d.ts +21 -0
- package/dist/src/cli/resolve-session.d.ts.map +1 -0
- package/dist/src/cli/resolve-session.js +40 -0
- package/dist/src/cli/resolve-session.js.map +1 -0
- package/dist/src/cli/resolve-session.test.d.ts +5 -0
- package/dist/src/cli/resolve-session.test.d.ts.map +1 -0
- package/dist/src/cli/resolve-session.test.js +112 -0
- package/dist/src/cli/resolve-session.test.js.map +1 -0
- package/dist/src/cli/script-executor.d.ts +1 -0
- package/dist/src/cli/script-executor.d.ts.map +1 -1
- package/dist/src/cli/script-executor.js +7 -1
- package/dist/src/cli/script-executor.js.map +1 -1
- package/dist/src/cli/types.d.ts +11 -0
- package/dist/src/cli/types.d.ts.map +1 -0
- package/dist/src/cli/types.js +5 -0
- package/dist/src/cli/types.js.map +1 -0
- package/dist/src/commands/connect.d.ts +16 -0
- package/dist/src/commands/connect.d.ts.map +1 -0
- package/dist/src/commands/connect.js +15 -0
- package/dist/src/commands/connect.js.map +1 -0
- package/dist/src/commands/connect.test.d.ts +5 -0
- package/dist/src/commands/connect.test.d.ts.map +1 -0
- package/dist/src/commands/connect.test.js +46 -0
- package/dist/src/commands/connect.test.js.map +1 -0
- package/dist/src/commands/console/exec/exec.d.ts +43 -0
- package/dist/src/commands/console/exec/exec.d.ts.map +1 -0
- package/dist/src/commands/console/exec/exec.js +79 -0
- package/dist/src/commands/console/exec/exec.js.map +1 -0
- package/dist/src/commands/console/exec/exec.test.d.ts +5 -0
- package/dist/src/commands/console/exec/exec.test.d.ts.map +1 -0
- package/dist/src/commands/console/exec/exec.test.js +191 -0
- package/dist/src/commands/console/exec/exec.test.js.map +1 -0
- package/dist/src/commands/console/logs/logs.d.ts +23 -0
- package/dist/src/commands/console/logs/logs.d.ts.map +1 -0
- package/dist/src/commands/console/logs/logs.js +80 -0
- package/dist/src/commands/console/logs/logs.js.map +1 -0
- package/dist/src/commands/console/logs/logs.test.d.ts +5 -0
- package/dist/src/commands/console/logs/logs.test.d.ts.map +1 -0
- package/dist/src/commands/console/logs/logs.test.js +111 -0
- package/dist/src/commands/console/logs/logs.test.js.map +1 -0
- package/dist/src/commands/disconnect.d.ts +9 -0
- package/dist/src/commands/disconnect.d.ts.map +1 -0
- package/dist/src/commands/disconnect.js +8 -0
- package/dist/src/commands/disconnect.js.map +1 -0
- package/dist/src/commands/disconnect.test.d.ts +5 -0
- package/dist/src/commands/disconnect.test.d.ts.map +1 -0
- package/dist/src/commands/disconnect.test.js +17 -0
- package/dist/src/commands/disconnect.test.js.map +1 -0
- package/dist/src/commands/explorer/query/query.d.ts +31 -0
- package/dist/src/commands/explorer/query/query.d.ts.map +1 -0
- package/dist/src/commands/explorer/query/query.js +106 -0
- package/dist/src/commands/explorer/query/query.js.map +1 -0
- package/dist/src/commands/explorer/query/query.test.d.ts +5 -0
- package/dist/src/commands/explorer/query/query.test.d.ts.map +1 -0
- package/dist/src/commands/explorer/query/query.test.js +228 -0
- package/dist/src/commands/explorer/query/query.test.js.map +1 -0
- package/dist/src/commands/formatters.test.d.ts +6 -0
- package/dist/src/commands/formatters.test.d.ts.map +1 -0
- package/dist/src/commands/formatters.test.js +211 -0
- package/dist/src/commands/formatters.test.js.map +1 -0
- package/dist/src/commands/framework/action-loader.d.ts +25 -0
- package/dist/src/commands/framework/action-loader.d.ts.map +1 -0
- package/dist/src/commands/framework/action-loader.js +46 -0
- package/dist/src/commands/framework/action-loader.js.map +1 -0
- package/dist/src/commands/framework/action-loader.test.d.ts +5 -0
- package/dist/src/commands/framework/action-loader.test.d.ts.map +1 -0
- package/dist/src/commands/framework/action-loader.test.js +89 -0
- package/dist/src/commands/framework/action-loader.test.js.map +1 -0
- package/dist/src/commands/framework/arg-builder.d.ts +92 -0
- package/dist/src/commands/framework/arg-builder.d.ts.map +1 -0
- package/dist/src/commands/framework/arg-builder.js +137 -0
- package/dist/src/commands/framework/arg-builder.js.map +1 -0
- package/dist/src/commands/framework/arg-builder.test.d.ts +5 -0
- package/dist/src/commands/framework/arg-builder.test.d.ts.map +1 -0
- package/dist/src/commands/framework/arg-builder.test.js +246 -0
- package/dist/src/commands/framework/arg-builder.test.js.map +1 -0
- package/dist/src/commands/framework/command-registry.d.ts +23 -0
- package/dist/src/commands/framework/command-registry.d.ts.map +1 -0
- package/dist/src/commands/framework/command-registry.js +42 -0
- package/dist/src/commands/framework/command-registry.js.map +1 -0
- package/dist/src/commands/framework/command-registry.test.d.ts +5 -0
- package/dist/src/commands/framework/command-registry.test.d.ts.map +1 -0
- package/dist/src/commands/framework/command-registry.test.js +158 -0
- package/dist/src/commands/framework/command-registry.test.js.map +1 -0
- package/dist/src/commands/framework/define-command.d.ts +76 -0
- package/dist/src/commands/framework/define-command.d.ts.map +1 -0
- package/dist/src/commands/framework/define-command.js +28 -0
- package/dist/src/commands/framework/define-command.js.map +1 -0
- package/dist/src/commands/framework/define-command.test.d.ts +5 -0
- package/dist/src/commands/framework/define-command.test.d.ts.map +1 -0
- package/dist/src/commands/framework/define-command.test.js +135 -0
- package/dist/src/commands/framework/define-command.test.js.map +1 -0
- package/dist/src/commands/framework/index.d.ts +8 -0
- package/dist/src/commands/framework/index.d.ts.map +1 -0
- package/dist/src/commands/framework/index.js +8 -0
- package/dist/src/commands/framework/index.js.map +1 -0
- package/dist/src/commands/index.d.ts +20 -0
- package/dist/src/commands/index.d.ts.map +1 -0
- package/dist/src/commands/index.js +20 -0
- package/dist/src/commands/index.js.map +1 -0
- package/dist/src/commands/linux/inject-credentials/inject-credentials.d.ts +15 -0
- package/dist/src/commands/linux/inject-credentials/inject-credentials.d.ts.map +1 -0
- package/dist/src/commands/linux/inject-credentials/inject-credentials.js +88 -0
- package/dist/src/commands/linux/inject-credentials/inject-credentials.js.map +1 -0
- package/dist/src/commands/linux/setup/setup.d.ts +19 -0
- package/dist/src/commands/linux/setup/setup.d.ts.map +1 -0
- package/dist/src/commands/linux/setup/setup.js +107 -0
- package/dist/src/commands/linux/setup/setup.js.map +1 -0
- package/dist/src/commands/linux/status/status.d.ts +34 -0
- package/dist/src/commands/linux/status/status.d.ts.map +1 -0
- package/dist/src/commands/linux/status/status.js +134 -0
- package/dist/src/commands/linux/status/status.js.map +1 -0
- package/dist/src/commands/plugin/install/install.d.ts +10 -0
- package/dist/src/commands/plugin/install/install.d.ts.map +1 -0
- package/dist/src/commands/plugin/install/install.js +23 -0
- package/dist/src/commands/plugin/install/install.js.map +1 -0
- package/dist/src/commands/plugin/uninstall/uninstall.d.ts +9 -0
- package/dist/src/commands/plugin/uninstall/uninstall.d.ts.map +1 -0
- package/dist/src/commands/plugin/uninstall/uninstall.js +41 -0
- package/dist/src/commands/plugin/uninstall/uninstall.js.map +1 -0
- package/dist/src/commands/process/close/close.d.ts +22 -0
- package/dist/src/commands/process/close/close.d.ts.map +1 -0
- package/dist/src/commands/process/close/close.js +34 -0
- package/dist/src/commands/process/close/close.js.map +1 -0
- package/dist/src/commands/process/format-state.d.ts +7 -0
- package/dist/src/commands/process/format-state.d.ts.map +1 -0
- package/dist/src/commands/process/format-state.js +19 -0
- package/dist/src/commands/process/format-state.js.map +1 -0
- package/dist/src/commands/process/info/info.d.ts +17 -0
- package/dist/src/commands/process/info/info.d.ts.map +1 -0
- package/dist/src/commands/process/info/info.js +38 -0
- package/dist/src/commands/process/info/info.js.map +1 -0
- package/dist/src/commands/process/info/info.test.d.ts +5 -0
- package/dist/src/commands/process/info/info.test.d.ts.map +1 -0
- package/dist/src/commands/process/info/info.test.js +58 -0
- package/dist/src/commands/process/info/info.test.js.map +1 -0
- package/dist/src/commands/process/launch/launch.d.ts +17 -0
- package/dist/src/commands/process/launch/launch.d.ts.map +1 -0
- package/dist/src/commands/process/launch/launch.js +26 -0
- package/dist/src/commands/process/launch/launch.js.map +1 -0
- package/dist/src/commands/process/launch/launch.test.d.ts +5 -0
- package/dist/src/commands/process/launch/launch.test.d.ts.map +1 -0
- package/dist/src/commands/process/launch/launch.test.js +49 -0
- package/dist/src/commands/process/launch/launch.test.js.map +1 -0
- package/dist/src/commands/process/list/list.d.ts +16 -0
- package/dist/src/commands/process/list/list.d.ts.map +1 -0
- package/dist/src/commands/process/list/list.js +56 -0
- package/dist/src/commands/process/list/list.js.map +1 -0
- package/dist/src/commands/process/list/list.test.d.ts +5 -0
- package/dist/src/commands/process/list/list.test.d.ts.map +1 -0
- package/dist/src/commands/process/list/list.test.js +71 -0
- package/dist/src/commands/process/list/list.test.js.map +1 -0
- package/dist/src/commands/process/run/run.d.ts +31 -0
- package/dist/src/commands/process/run/run.d.ts.map +1 -0
- package/dist/src/commands/process/run/run.js +63 -0
- package/dist/src/commands/process/run/run.js.map +1 -0
- package/dist/src/commands/rgba-to-png.d.ts +17 -0
- package/dist/src/commands/rgba-to-png.d.ts.map +1 -0
- package/dist/src/commands/rgba-to-png.js +85 -0
- package/dist/src/commands/rgba-to-png.js.map +1 -0
- package/dist/src/commands/serve/serve.d.ts +17 -0
- package/dist/src/commands/serve/serve.d.ts.map +1 -0
- package/dist/src/commands/serve/serve.js +128 -0
- package/dist/src/commands/serve/serve.js.map +1 -0
- package/dist/src/commands/serve/serve.test.d.ts +5 -0
- package/dist/src/commands/serve/serve.test.d.ts.map +1 -0
- package/dist/src/commands/serve/serve.test.js +100 -0
- package/dist/src/commands/serve/serve.test.js.map +1 -0
- package/dist/src/commands/viewport/screenshot/screenshot.d.ts +17 -0
- package/dist/src/commands/viewport/screenshot/screenshot.d.ts.map +1 -0
- package/dist/src/commands/viewport/screenshot/screenshot.js +45 -0
- package/dist/src/commands/viewport/screenshot/screenshot.js.map +1 -0
- package/dist/src/commands/viewport/screenshot/screenshot.test.d.ts +5 -0
- package/dist/src/commands/viewport/screenshot/screenshot.test.d.ts.map +1 -0
- package/dist/src/commands/viewport/screenshot/screenshot.test.js +143 -0
- package/dist/src/commands/viewport/screenshot/screenshot.test.js.map +1 -0
- package/dist/src/docker/docker-delegator.d.ts +30 -0
- package/dist/src/docker/docker-delegator.d.ts.map +1 -0
- package/dist/src/docker/docker-delegator.js +201 -0
- package/dist/src/docker/docker-delegator.js.map +1 -0
- package/dist/src/docker/docker-delegator.test.d.ts +2 -0
- package/dist/src/docker/docker-delegator.test.d.ts.map +1 -0
- package/dist/src/docker/docker-delegator.test.js +132 -0
- package/dist/src/docker/docker-delegator.test.js.map +1 -0
- package/dist/src/index.d.ts +9 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/index.test.d.ts +2 -0
- package/dist/src/index.test.d.ts.map +1 -0
- package/dist/src/index.test.js +51 -0
- package/dist/src/index.test.js.map +1 -0
- package/dist/src/linux/index.d.ts +12 -0
- package/dist/src/linux/index.d.ts.map +1 -0
- package/dist/src/linux/index.js +11 -0
- package/dist/src/linux/index.js.map +1 -0
- package/dist/src/linux/linux-config.d.ts +37 -0
- package/dist/src/linux/linux-config.d.ts.map +1 -0
- package/dist/src/linux/linux-config.js +70 -0
- package/dist/src/linux/linux-config.js.map +1 -0
- package/dist/src/linux/linux-config.test.d.ts +2 -0
- package/dist/src/linux/linux-config.test.d.ts.map +1 -0
- package/dist/src/linux/linux-config.test.js +54 -0
- package/dist/src/linux/linux-config.test.js.map +1 -0
- package/dist/src/linux/linux-credential-writer.d.ts +35 -0
- package/dist/src/linux/linux-credential-writer.d.ts.map +1 -0
- package/dist/src/linux/linux-credential-writer.js +300 -0
- package/dist/src/linux/linux-credential-writer.js.map +1 -0
- package/dist/src/linux/linux-display-manager.d.ts +24 -0
- package/dist/src/linux/linux-display-manager.d.ts.map +1 -0
- package/dist/src/linux/linux-display-manager.js +92 -0
- package/dist/src/linux/linux-display-manager.js.map +1 -0
- package/dist/src/linux/linux-env-guard.d.ts +13 -0
- package/dist/src/linux/linux-env-guard.d.ts.map +1 -0
- package/dist/src/linux/linux-env-guard.js +31 -0
- package/dist/src/linux/linux-env-guard.js.map +1 -0
- package/dist/src/linux/linux-env-guard.test.d.ts +2 -0
- package/dist/src/linux/linux-env-guard.test.d.ts.map +1 -0
- package/dist/src/linux/linux-env-guard.test.js +48 -0
- package/dist/src/linux/linux-env-guard.test.js.map +1 -0
- package/dist/src/linux/linux-fflags.d.ts +17 -0
- package/dist/src/linux/linux-fflags.d.ts.map +1 -0
- package/dist/src/linux/linux-fflags.js +33 -0
- package/dist/src/linux/linux-fflags.js.map +1 -0
- package/dist/src/linux/linux-fflags.test.d.ts +2 -0
- package/dist/src/linux/linux-fflags.test.d.ts.map +1 -0
- package/dist/src/linux/linux-fflags.test.js +55 -0
- package/dist/src/linux/linux-fflags.test.js.map +1 -0
- package/dist/src/linux/linux-prerequisites.d.ts +24 -0
- package/dist/src/linux/linux-prerequisites.d.ts.map +1 -0
- package/dist/src/linux/linux-prerequisites.js +118 -0
- package/dist/src/linux/linux-prerequisites.js.map +1 -0
- package/dist/src/linux/linux-shader-patcher.d.ts +17 -0
- package/dist/src/linux/linux-shader-patcher.d.ts.map +1 -0
- package/dist/src/linux/linux-shader-patcher.js +48 -0
- package/dist/src/linux/linux-shader-patcher.js.map +1 -0
- package/dist/src/linux/linux-shader-patcher.test.d.ts +2 -0
- package/dist/src/linux/linux-shader-patcher.test.d.ts.map +1 -0
- package/dist/src/linux/linux-shader-patcher.test.js +55 -0
- package/dist/src/linux/linux-shader-patcher.test.js.map +1 -0
- package/dist/src/linux/linux-studio-installer.d.ts +10 -0
- package/dist/src/linux/linux-studio-installer.d.ts.map +1 -0
- package/dist/src/linux/linux-studio-installer.js +79 -0
- package/dist/src/linux/linux-studio-installer.js.map +1 -0
- package/dist/src/linux/linux-studio-launcher.d.ts +10 -0
- package/dist/src/linux/linux-studio-launcher.d.ts.map +1 -0
- package/dist/src/linux/linux-studio-launcher.js +73 -0
- package/dist/src/linux/linux-studio-launcher.js.map +1 -0
- package/dist/src/linux/linux-version-resolver.d.ts +18 -0
- package/dist/src/linux/linux-version-resolver.d.ts.map +1 -0
- package/dist/src/linux/linux-version-resolver.js +49 -0
- package/dist/src/linux/linux-version-resolver.js.map +1 -0
- package/dist/src/linux/linux-wine-env.d.ts +11 -0
- package/dist/src/linux/linux-wine-env.d.ts.map +1 -0
- package/dist/src/linux/linux-wine-env.js +33 -0
- package/dist/src/linux/linux-wine-env.js.map +1 -0
- package/dist/src/linux/linux-wine-env.test.d.ts +2 -0
- package/dist/src/linux/linux-wine-env.test.d.ts.map +1 -0
- package/dist/src/linux/linux-wine-env.test.js +47 -0
- package/dist/src/linux/linux-wine-env.test.js.map +1 -0
- package/dist/src/plugin/persistent-plugin-installer.d.ts +21 -0
- package/dist/src/plugin/persistent-plugin-installer.d.ts.map +1 -0
- package/dist/src/plugin/persistent-plugin-installer.js +69 -0
- package/dist/src/plugin/persistent-plugin-installer.js.map +1 -0
- package/dist/src/plugin/persistent-plugin-installer.test.d.ts +5 -0
- package/dist/src/plugin/persistent-plugin-installer.test.d.ts.map +1 -0
- package/dist/src/plugin/persistent-plugin-installer.test.js +109 -0
- package/dist/src/plugin/persistent-plugin-installer.test.js.map +1 -0
- package/dist/src/plugin/plugin-discovery.d.ts +7 -0
- package/dist/src/plugin/plugin-discovery.d.ts.map +1 -0
- package/dist/src/plugin/plugin-discovery.js +18 -0
- package/dist/src/plugin/plugin-discovery.js.map +1 -0
- package/dist/src/plugin/plugin-discovery.test.d.ts +5 -0
- package/dist/src/plugin/plugin-discovery.test.d.ts.map +1 -0
- package/dist/src/plugin/plugin-discovery.test.js +55 -0
- package/dist/src/plugin/plugin-discovery.test.js.map +1 -0
- package/dist/src/plugin/plugin-injector.js +1 -1
- package/dist/src/plugin/plugin-injector.js.map +1 -1
- package/dist/src/process/studio-process-manager.d.ts +7 -3
- package/dist/src/process/studio-process-manager.d.ts.map +1 -1
- package/dist/src/process/studio-process-manager.js +38 -11
- package/dist/src/process/studio-process-manager.js.map +1 -1
- package/dist/src/process/studio-process-manager.test.js +18 -1
- package/dist/src/process/studio-process-manager.test.js.map +1 -1
- package/dist/src/server/action-dispatcher.d.ts +35 -0
- package/dist/src/server/action-dispatcher.d.ts.map +1 -0
- package/dist/src/server/action-dispatcher.js +67 -0
- package/dist/src/server/action-dispatcher.js.map +1 -0
- package/dist/src/server/action-dispatcher.test.d.ts +6 -0
- package/dist/src/server/action-dispatcher.test.d.ts.map +1 -0
- package/dist/src/server/action-dispatcher.test.js +173 -0
- package/dist/src/server/action-dispatcher.test.js.map +1 -0
- package/dist/src/server/index.d.ts +1 -1
- package/dist/src/server/index.d.ts.map +1 -1
- package/dist/src/server/pending-request-map.d.ts +33 -0
- package/dist/src/server/pending-request-map.d.ts.map +1 -0
- package/dist/src/server/pending-request-map.js +69 -0
- package/dist/src/server/pending-request-map.js.map +1 -0
- package/dist/src/server/pending-request-map.test.d.ts +2 -0
- package/dist/src/server/pending-request-map.test.d.ts.map +1 -0
- package/dist/src/server/pending-request-map.test.js +192 -0
- package/dist/src/server/pending-request-map.test.js.map +1 -0
- package/dist/src/server/plugin-detection.test.d.ts +7 -0
- package/dist/src/server/plugin-detection.test.d.ts.map +1 -0
- package/dist/src/server/plugin-detection.test.js +154 -0
- package/dist/src/server/plugin-detection.test.js.map +1 -0
- package/dist/src/server/studio-bridge-server.d.ts +44 -7
- package/dist/src/server/studio-bridge-server.d.ts.map +1 -1
- package/dist/src/server/studio-bridge-server.js +341 -91
- package/dist/src/server/studio-bridge-server.js.map +1 -1
- package/dist/src/server/studio-bridge-server.test.js +231 -207
- package/dist/src/server/studio-bridge-server.test.js.map +1 -1
- package/dist/src/server/web-socket-protocol-basic.test.d.ts +2 -0
- package/dist/src/server/web-socket-protocol-basic.test.d.ts.map +1 -0
- package/dist/src/server/web-socket-protocol-basic.test.js +98 -0
- package/dist/src/server/web-socket-protocol-basic.test.js.map +1 -0
- package/dist/src/server/web-socket-protocol.d.ts +218 -20
- package/dist/src/server/web-socket-protocol.d.ts.map +1 -1
- package/dist/src/server/web-socket-protocol.js +346 -20
- package/dist/src/server/web-socket-protocol.js.map +1 -1
- package/dist/src/server/web-socket-protocol.test.js +572 -146
- package/dist/src/server/web-socket-protocol.test.js.map +1 -1
- package/dist/src/test/e2e/hand-off.test.d.ts +9 -0
- package/dist/src/test/e2e/hand-off.test.d.ts.map +1 -0
- package/dist/src/test/e2e/hand-off.test.js +274 -0
- package/dist/src/test/e2e/hand-off.test.js.map +1 -0
- package/dist/src/test/e2e/persistent-session.test.d.ts +11 -0
- package/dist/src/test/e2e/persistent-session.test.d.ts.map +1 -0
- package/dist/src/test/e2e/persistent-session.test.js +367 -0
- package/dist/src/test/e2e/persistent-session.test.js.map +1 -0
- package/dist/src/test/e2e/split-server.test.d.ts +14 -0
- package/dist/src/test/e2e/split-server.test.d.ts.map +1 -0
- package/dist/src/test/e2e/split-server.test.js +230 -0
- package/dist/src/test/e2e/split-server.test.js.map +1 -0
- package/dist/src/test/helpers/mock-plugin-client.d.ts +69 -0
- package/dist/src/test/helpers/mock-plugin-client.d.ts.map +1 -0
- package/dist/src/test/helpers/mock-plugin-client.js +213 -0
- package/dist/src/test/helpers/mock-plugin-client.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docker/.dockerignore +2 -0
- package/docker/Dockerfile +113 -0
- package/docker/docker-compose.yml +20 -0
- package/docker/entrypoint.sh +19 -0
- package/package.json +8 -6
- package/src/bridge/bridge-connection-remote.test.ts +189 -0
- package/src/bridge/bridge-connection.test.ts +1076 -0
- package/src/bridge/bridge-connection.ts +718 -0
- package/src/bridge/bridge-session.test.ts +336 -0
- package/src/bridge/bridge-session.ts +365 -0
- package/src/bridge/index.ts +42 -0
- package/src/bridge/internal/__tests__/failover-crash.test.ts +191 -0
- package/src/bridge/internal/__tests__/failover-graceful.test.ts +268 -0
- package/src/bridge/internal/__tests__/failover-inflight.test.ts +329 -0
- package/src/bridge/internal/__tests__/host-client-integration.test.ts +387 -0
- package/src/bridge/internal/bridge-client.test.ts +399 -0
- package/src/bridge/internal/bridge-client.ts +434 -0
- package/src/bridge/internal/bridge-host.test.ts +501 -0
- package/src/bridge/internal/bridge-host.ts +531 -0
- package/src/bridge/internal/environment-detection.test.ts +180 -0
- package/src/bridge/internal/environment-detection.ts +119 -0
- package/src/bridge/internal/hand-off.test.ts +408 -0
- package/src/bridge/internal/hand-off.ts +275 -0
- package/src/bridge/internal/health-endpoint.test.ts +147 -0
- package/src/bridge/internal/health-endpoint.ts +100 -0
- package/src/bridge/internal/host-protocol.test.ts +415 -0
- package/src/bridge/internal/host-protocol.ts +255 -0
- package/src/bridge/internal/session-tracker.test.ts +535 -0
- package/src/bridge/internal/session-tracker.ts +198 -0
- package/src/bridge/internal/transport-client.test.ts +241 -0
- package/src/bridge/internal/transport-client.ts +194 -0
- package/src/bridge/internal/transport-server.test.ts +220 -0
- package/src/bridge/internal/transport-server.ts +242 -0
- package/src/bridge/types.ts +161 -0
- package/src/cli/adapters/cli-command-adapter-handler.test.ts +318 -0
- package/src/cli/adapters/cli-command-adapter.test.ts +221 -0
- package/src/cli/adapters/cli-command-adapter.ts +342 -0
- package/src/cli/adapters/group-builder.test.ts +146 -0
- package/src/cli/adapters/group-builder.ts +81 -0
- package/src/cli/adapters/help-formatter.test.ts +97 -0
- package/src/cli/adapters/help-formatter.ts +86 -0
- package/src/cli/adapters/target-resolver.test.ts +222 -0
- package/src/cli/adapters/target-resolver.ts +144 -0
- package/src/cli/args/global-args.ts +2 -0
- package/src/cli/cli.ts +100 -21
- package/src/cli/resolve-script-content.ts +36 -0
- package/src/cli/resolve-session.test.ts +141 -0
- package/src/cli/resolve-session.ts +66 -0
- package/src/cli/script-executor.ts +22 -4
- package/src/cli/types.ts +11 -0
- package/src/commands/connect.test.ts +61 -0
- package/src/commands/connect.ts +32 -0
- package/src/commands/console/exec/exec.test.ts +258 -0
- package/src/commands/console/exec/exec.ts +130 -0
- package/src/commands/console/exec/execute.luau +202 -0
- package/src/commands/console/logs/logs.test.ts +138 -0
- package/src/commands/console/logs/logs.ts +115 -0
- package/src/commands/console/logs/query-logs.luau +76 -0
- package/src/commands/disconnect.test.ts +21 -0
- package/src/commands/disconnect.ts +12 -0
- package/src/commands/explorer/query/query-data-model.luau +206 -0
- package/src/commands/explorer/query/query.test.ts +297 -0
- package/src/commands/explorer/query/query.ts +157 -0
- package/src/commands/formatters.test.ts +237 -0
- package/src/commands/framework/action-loader.test.ts +118 -0
- package/src/commands/framework/action-loader.ts +65 -0
- package/src/commands/framework/arg-builder.test.ts +298 -0
- package/src/commands/framework/arg-builder.ts +203 -0
- package/src/commands/framework/command-registry.test.ts +204 -0
- package/src/commands/framework/command-registry.ts +51 -0
- package/src/commands/framework/define-command.test.ts +161 -0
- package/src/commands/framework/define-command.ts +114 -0
- package/src/commands/framework/index.ts +33 -0
- package/src/commands/index.ts +72 -0
- package/src/commands/linux/inject-credentials/inject-credentials.ts +118 -0
- package/src/commands/linux/setup/setup.ts +145 -0
- package/src/commands/linux/status/status.ts +180 -0
- package/src/commands/plugin/install/install.ts +31 -0
- package/src/commands/plugin/uninstall/uninstall.ts +54 -0
- package/src/commands/process/close/close.ts +52 -0
- package/src/commands/process/format-state.ts +21 -0
- package/src/commands/process/info/info.test.ts +76 -0
- package/src/commands/process/info/info.ts +54 -0
- package/src/commands/process/info/query-state.luau +48 -0
- package/src/commands/process/launch/launch.test.ts +65 -0
- package/src/commands/process/launch/launch.ts +45 -0
- package/src/commands/process/list/list.test.ts +82 -0
- package/src/commands/process/list/list.ts +75 -0
- package/src/commands/process/run/run.ts +98 -0
- package/src/commands/rgba-to-png.ts +98 -0
- package/src/commands/serve/serve.test.ts +139 -0
- package/src/commands/serve/serve.ts +161 -0
- package/src/commands/viewport/screenshot/capture-screenshot.luau +247 -0
- package/src/commands/viewport/screenshot/screenshot.test.ts +181 -0
- package/src/commands/viewport/screenshot/screenshot.ts +71 -0
- package/src/docker/docker-delegator.test.ts +159 -0
- package/src/docker/docker-delegator.ts +240 -0
- package/src/index.test.ts +58 -0
- package/src/index.ts +104 -3
- package/src/linux/README.md +130 -0
- package/src/linux/index.ts +25 -0
- package/src/linux/linux-config.test.ts +66 -0
- package/src/linux/linux-config.ts +102 -0
- package/src/linux/linux-credential-writer.ts +421 -0
- package/src/linux/linux-display-manager.ts +106 -0
- package/src/linux/linux-env-guard.test.ts +62 -0
- package/src/linux/linux-env-guard.ts +38 -0
- package/src/linux/linux-fflags.test.ts +78 -0
- package/src/linux/linux-fflags.ts +48 -0
- package/src/linux/linux-prerequisites.ts +152 -0
- package/src/linux/linux-shader-patcher.test.ts +76 -0
- package/src/linux/linux-shader-patcher.ts +56 -0
- package/src/linux/linux-studio-installer.ts +113 -0
- package/src/linux/linux-studio-launcher.ts +90 -0
- package/src/linux/linux-version-resolver.ts +74 -0
- package/src/linux/linux-wine-env.test.ts +56 -0
- package/src/linux/linux-wine-env.ts +38 -0
- package/src/linux/write-cred.c +48 -0
- package/src/plugin/persistent-plugin-installer.test.ts +168 -0
- package/src/plugin/persistent-plugin-installer.ts +90 -0
- package/src/plugin/plugin-discovery.test.ts +70 -0
- package/src/plugin/plugin-discovery.ts +21 -0
- package/src/plugin/plugin-injector.ts +1 -1
- package/src/process/studio-process-manager.test.ts +22 -1
- package/src/process/studio-process-manager.ts +57 -18
- package/src/server/action-dispatcher.test.ts +240 -0
- package/src/server/action-dispatcher.ts +89 -0
- package/src/server/index.ts +0 -3
- package/src/server/pending-request-map.test.ts +261 -0
- package/src/server/pending-request-map.ts +87 -0
- package/src/server/plugin-detection.test.ts +195 -0
- package/src/server/studio-bridge-server.test.ts +321 -283
- package/src/server/studio-bridge-server.ts +469 -111
- package/src/server/web-socket-protocol-basic.test.ts +131 -0
- package/src/server/web-socket-protocol.test.ts +658 -159
- package/src/server/web-socket-protocol.ts +668 -58
- package/src/test/e2e/hand-off.test.ts +338 -0
- package/src/test/e2e/persistent-session.test.ts +442 -0
- package/src/test/e2e/split-server.test.ts +290 -0
- package/src/test/helpers/mock-plugin-client.ts +276 -0
- package/templates/studio-bridge-plugin/src/Shared/ActionRouter.luau +245 -0
- package/templates/studio-bridge-plugin/src/Shared/DiscoveryStateMachine.luau +203 -0
- package/templates/studio-bridge-plugin/src/Shared/MessageBuffer.luau +144 -0
- package/templates/studio-bridge-plugin/src/Shared/Protocol.luau +132 -0
- package/templates/studio-bridge-plugin/src/StudioBridgePlugin.server.lua +364 -133
- package/templates/studio-bridge-plugin/src/Vendor/png.luau +1247 -0
- package/templates/studio-bridge-plugin-test/test/actions.test.luau +580 -0
- package/templates/studio-bridge-plugin-test/test/discovery.test.luau +622 -0
- package/templates/studio-bridge-plugin-test/test/execute-handler.test.luau +406 -0
- package/templates/studio-bridge-plugin-test/test/hash-lifecycle.test.luau +814 -0
- package/templates/studio-bridge-plugin-test/test/integration.test.luau +1020 -0
- package/templates/studio-bridge-plugin-test/test/new-actions.test.luau +339 -0
- package/templates/studio-bridge-plugin-test/test/plugin-entry.test.luau +493 -0
- package/templates/studio-bridge-plugin-test/test/protocol.test.luau +506 -0
- package/templates/studio-bridge-plugin-test/test/roblox-mocks.luau +108 -0
- package/templates/studio-bridge-plugin-test/test/test-runner.luau +112 -0
- package/dist/src/cli/commands/exec-command.d.ts +0 -15
- package/dist/src/cli/commands/exec-command.d.ts.map +0 -1
- package/dist/src/cli/commands/exec-command.js +0 -35
- package/dist/src/cli/commands/exec-command.js.map +0 -1
- package/dist/src/cli/commands/run-command.d.ts +0 -15
- package/dist/src/cli/commands/run-command.d.ts.map +0 -1
- package/dist/src/cli/commands/run-command.js +0 -47
- package/dist/src/cli/commands/run-command.js.map +0 -1
- package/dist/src/cli/commands/terminal/terminal-command.d.ts +0 -17
- package/dist/src/cli/commands/terminal/terminal-command.d.ts.map +0 -1
- package/dist/src/cli/commands/terminal/terminal-command.js +0 -41
- package/dist/src/cli/commands/terminal/terminal-command.js.map +0 -1
- package/dist/src/cli/commands/terminal/terminal-editor.d.ts +0 -43
- package/dist/src/cli/commands/terminal/terminal-editor.d.ts.map +0 -1
- package/dist/src/cli/commands/terminal/terminal-editor.js +0 -430
- package/dist/src/cli/commands/terminal/terminal-editor.js.map +0 -1
- package/dist/src/cli/commands/terminal/terminal-mode.d.ts +0 -13
- package/dist/src/cli/commands/terminal/terminal-mode.d.ts.map +0 -1
- package/dist/src/cli/commands/terminal/terminal-mode.js +0 -141
- package/dist/src/cli/commands/terminal/terminal-mode.js.map +0 -1
- package/dist/src/server/web-socket-protocol.smoke.test.d.ts +0 -6
- package/dist/src/server/web-socket-protocol.smoke.test.d.ts.map +0 -1
- package/dist/src/server/web-socket-protocol.smoke.test.js +0 -196
- package/dist/src/server/web-socket-protocol.smoke.test.js.map +0 -1
- package/src/cli/commands/exec-command.ts +0 -48
- package/src/cli/commands/run-command.ts +0 -63
- package/src/cli/commands/terminal/terminal-command.ts +0 -54
- package/src/cli/commands/terminal/terminal-editor.ts +0 -500
- package/src/cli/commands/terminal/terminal-mode.ts +0 -184
- package/src/server/web-socket-protocol.smoke.test.ts +0 -255
|
@@ -8,11 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
10
10
|
import { WebSocket } from 'ws';
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// ---------------------------------------------------------------------------
|
|
11
|
+
import {
|
|
12
|
+
StudioBridgeServer,
|
|
13
|
+
type StudioBridgePhase,
|
|
14
|
+
} from './studio-bridge-server.js';
|
|
16
15
|
|
|
17
16
|
vi.mock('@quenty/nevermore-template-helpers', () => ({
|
|
18
17
|
BuildContext: {
|
|
@@ -42,13 +41,9 @@ vi.mock('../process/studio-process-manager.js', () => ({
|
|
|
42
41
|
findPluginsFolder: vi.fn(() => '/fake/plugins'),
|
|
43
42
|
}));
|
|
44
43
|
|
|
45
|
-
// ---------------------------------------------------------------------------
|
|
46
|
-
// Helpers
|
|
47
|
-
// ---------------------------------------------------------------------------
|
|
48
|
-
|
|
49
44
|
/**
|
|
50
|
-
* Connect a WebSocket client to the server and
|
|
51
|
-
*
|
|
45
|
+
* Connect a WebSocket client to the server and send a register message,
|
|
46
|
+
* returning the connected client.
|
|
52
47
|
*/
|
|
53
48
|
async function connectAndHandshake(
|
|
54
49
|
port: number,
|
|
@@ -61,20 +56,22 @@ async function connectAndHandshake(
|
|
|
61
56
|
ws.on('error', reject);
|
|
62
57
|
});
|
|
63
58
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
59
|
+
ws.send(
|
|
60
|
+
JSON.stringify({
|
|
61
|
+
type: 'register',
|
|
62
|
+
sessionId,
|
|
63
|
+
payload: {
|
|
64
|
+
pluginVersion: '1.0.0',
|
|
65
|
+
instanceId: 'inst-1',
|
|
66
|
+
placeName: 'TestPlace',
|
|
67
|
+
state: 'Edit',
|
|
68
|
+
capabilities: ['execute', 'queryState'],
|
|
69
|
+
},
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
// Allow the server to process the register message
|
|
74
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
78
75
|
|
|
79
76
|
return ws;
|
|
80
77
|
}
|
|
@@ -85,7 +82,11 @@ async function connectAndHandshake(
|
|
|
85
82
|
* and the port.
|
|
86
83
|
*/
|
|
87
84
|
async function createReadyServer(
|
|
88
|
-
options: {
|
|
85
|
+
options: {
|
|
86
|
+
sessionId?: string;
|
|
87
|
+
timeoutMs?: number;
|
|
88
|
+
onPhase?: (p: StudioBridgePhase) => void;
|
|
89
|
+
} = {}
|
|
89
90
|
) {
|
|
90
91
|
const sessionId = options.sessionId ?? 'test-session';
|
|
91
92
|
const server = new StudioBridgeServer({
|
|
@@ -98,16 +99,14 @@ async function createReadyServer(
|
|
|
98
99
|
// Start in background — it will wait for handshake
|
|
99
100
|
const startPromise = server.startAsync();
|
|
100
101
|
|
|
101
|
-
// We need to discover the port the server is listening on. The
|
|
102
|
-
// created inside startAsync and we can't access it directly. However, we
|
|
102
|
+
// We need to discover the port the server is listening on. The HTTP server
|
|
103
|
+
// is created inside startAsync and we can't access it directly. However, we
|
|
103
104
|
// know the mock for launchStudioAsync will resolve immediately, so the
|
|
104
105
|
// server will be waiting for a handshake. We just need the port.
|
|
105
106
|
// Access it via the private field (acceptable in tests).
|
|
106
|
-
// Wait a tick for the
|
|
107
|
+
// Wait a tick for the HTTP server to be created
|
|
107
108
|
await new Promise((r) => setTimeout(r, 50));
|
|
108
|
-
const
|
|
109
|
-
const addr = wss.address();
|
|
110
|
-
const port: number = addr.port;
|
|
109
|
+
const port: number = (server as any)._port;
|
|
111
110
|
|
|
112
111
|
// Simulate plugin connecting and performing handshake
|
|
113
112
|
const client = await connectAndHandshake(port, sessionId);
|
|
@@ -118,10 +117,6 @@ async function createReadyServer(
|
|
|
118
117
|
return { server, client, port, sessionId };
|
|
119
118
|
}
|
|
120
119
|
|
|
121
|
-
// ---------------------------------------------------------------------------
|
|
122
|
-
// Tests
|
|
123
|
-
// ---------------------------------------------------------------------------
|
|
124
|
-
|
|
125
120
|
describe('StudioBridgeServer', () => {
|
|
126
121
|
let server: StudioBridgeServer | undefined;
|
|
127
122
|
let client: WebSocket | undefined;
|
|
@@ -138,10 +133,6 @@ describe('StudioBridgeServer', () => {
|
|
|
138
133
|
server = undefined;
|
|
139
134
|
});
|
|
140
135
|
|
|
141
|
-
// -----------------------------------------------------------------------
|
|
142
|
-
// State machine guards
|
|
143
|
-
// -----------------------------------------------------------------------
|
|
144
|
-
|
|
145
136
|
describe('state guards', () => {
|
|
146
137
|
it('throws when executeAsync is called before startAsync', async () => {
|
|
147
138
|
server = new StudioBridgeServer({ placePath: '/fake/place.rbxl' });
|
|
@@ -171,64 +162,17 @@ describe('StudioBridgeServer', () => {
|
|
|
171
162
|
});
|
|
172
163
|
});
|
|
173
164
|
|
|
174
|
-
// -----------------------------------------------------------------------
|
|
175
|
-
// Handshake
|
|
176
|
-
// -----------------------------------------------------------------------
|
|
177
|
-
|
|
178
165
|
describe('handshake', () => {
|
|
179
|
-
it('accepts
|
|
166
|
+
it('accepts register with correct session ID', async () => {
|
|
180
167
|
const ready = await createReadyServer({ sessionId: 'my-session' });
|
|
181
168
|
server = ready.server;
|
|
182
169
|
client = ready.client;
|
|
183
170
|
|
|
184
|
-
// If we got here
|
|
185
|
-
//
|
|
171
|
+
// If we got here the server accepted the register handshake and
|
|
172
|
+
// resolved startAsync — connectAndHandshake yields the connected client.
|
|
186
173
|
expect(true).toBe(true);
|
|
187
174
|
});
|
|
188
175
|
|
|
189
|
-
it('rejects hello with wrong session ID and closes connection', async () => {
|
|
190
|
-
const sessionId = 'correct-session';
|
|
191
|
-
server = new StudioBridgeServer({
|
|
192
|
-
placePath: '/fake/place.rbxl',
|
|
193
|
-
sessionId,
|
|
194
|
-
timeoutMs: 1_000,
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
const startPromise = server.startAsync();
|
|
198
|
-
|
|
199
|
-
await new Promise((r) => setTimeout(r, 50));
|
|
200
|
-
const wss = (server as any)._wss;
|
|
201
|
-
const port: number = wss.address().port;
|
|
202
|
-
|
|
203
|
-
// Connect with correct path but wrong session ID in message
|
|
204
|
-
const ws = new WebSocket(`ws://localhost:${port}/${sessionId}`);
|
|
205
|
-
await new Promise<void>((resolve, reject) => {
|
|
206
|
-
ws.on('open', resolve);
|
|
207
|
-
ws.on('error', reject);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
// Track if server closes the connection
|
|
211
|
-
const closedPromise = new Promise<void>((resolve) => {
|
|
212
|
-
ws.on('close', () => resolve());
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
ws.send(
|
|
216
|
-
JSON.stringify({
|
|
217
|
-
type: 'hello',
|
|
218
|
-
sessionId: 'wrong-session',
|
|
219
|
-
payload: { sessionId: 'wrong-session' },
|
|
220
|
-
})
|
|
221
|
-
);
|
|
222
|
-
|
|
223
|
-
// Server should close the connection
|
|
224
|
-
await closedPromise;
|
|
225
|
-
|
|
226
|
-
// Server should NOT accept — startAsync should time out
|
|
227
|
-
await expect(startPromise).rejects.toThrow('Timed out waiting for Studio plugin handshake');
|
|
228
|
-
|
|
229
|
-
// Server already stopped on failure (startAsync catch cleans up)
|
|
230
|
-
});
|
|
231
|
-
|
|
232
176
|
it('rejects connection to wrong WebSocket path', async () => {
|
|
233
177
|
const sessionId = 'correct-session';
|
|
234
178
|
server = new StudioBridgeServer({
|
|
@@ -240,8 +184,7 @@ describe('StudioBridgeServer', () => {
|
|
|
240
184
|
const startPromise = server.startAsync();
|
|
241
185
|
|
|
242
186
|
await new Promise((r) => setTimeout(r, 50));
|
|
243
|
-
const
|
|
244
|
-
const port: number = wss.address().port;
|
|
187
|
+
const port: number = (server as any)._port;
|
|
245
188
|
|
|
246
189
|
// Connect with wrong path
|
|
247
190
|
const ws = new WebSocket(`ws://localhost:${port}/wrong-path`);
|
|
@@ -258,14 +201,12 @@ describe('StudioBridgeServer', () => {
|
|
|
258
201
|
expect(['error', 'rejected']).toContain(errorOrClose);
|
|
259
202
|
|
|
260
203
|
// startAsync should time out
|
|
261
|
-
await expect(startPromise).rejects.toThrow(
|
|
204
|
+
await expect(startPromise).rejects.toThrow(
|
|
205
|
+
'Timed out waiting for Studio plugin handshake'
|
|
206
|
+
);
|
|
262
207
|
});
|
|
263
208
|
});
|
|
264
209
|
|
|
265
|
-
// -----------------------------------------------------------------------
|
|
266
|
-
// Script execution
|
|
267
|
-
// -----------------------------------------------------------------------
|
|
268
|
-
|
|
269
210
|
describe('executeAsync', () => {
|
|
270
211
|
it('sends execute message with sessionId and returns result on scriptComplete', async () => {
|
|
271
212
|
const ready = await createReadyServer();
|
|
@@ -273,16 +214,21 @@ describe('StudioBridgeServer', () => {
|
|
|
273
214
|
client = ready.client;
|
|
274
215
|
|
|
275
216
|
// Listen for execute message from server
|
|
276
|
-
const executePromise = new Promise<{ script: string; sessionId: string }>(
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
217
|
+
const executePromise = new Promise<{ script: string; sessionId: string }>(
|
|
218
|
+
(resolve) => {
|
|
219
|
+
client!.on('message', (raw) => {
|
|
220
|
+
const data = JSON.parse(
|
|
221
|
+
typeof raw === 'string' ? raw : raw.toString('utf-8')
|
|
222
|
+
);
|
|
223
|
+
if (data.type === 'execute') {
|
|
224
|
+
resolve({
|
|
225
|
+
script: data.payload.script,
|
|
226
|
+
sessionId: data.sessionId,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
);
|
|
286
232
|
|
|
287
233
|
// Start execution
|
|
288
234
|
const resultPromise = server.executeAsync({
|
|
@@ -308,117 +254,6 @@ describe('StudioBridgeServer', () => {
|
|
|
308
254
|
expect(result.logs).toBe('');
|
|
309
255
|
});
|
|
310
256
|
|
|
311
|
-
it('collects output messages into logs', async () => {
|
|
312
|
-
const ready = await createReadyServer();
|
|
313
|
-
server = ready.server;
|
|
314
|
-
client = ready.client;
|
|
315
|
-
|
|
316
|
-
const resultPromise = server.executeAsync({
|
|
317
|
-
scriptContent: 'print("test")',
|
|
318
|
-
});
|
|
319
|
-
|
|
320
|
-
// Wait for execute message to arrive
|
|
321
|
-
await new Promise<void>((resolve) => {
|
|
322
|
-
client!.on('message', (raw) => {
|
|
323
|
-
const data = JSON.parse(
|
|
324
|
-
typeof raw === 'string' ? raw : raw.toString('utf-8')
|
|
325
|
-
);
|
|
326
|
-
if (data.type === 'execute') resolve();
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
// Send output messages
|
|
331
|
-
client!.send(
|
|
332
|
-
JSON.stringify({
|
|
333
|
-
type: 'output',
|
|
334
|
-
sessionId: ready.sessionId,
|
|
335
|
-
payload: {
|
|
336
|
-
messages: [
|
|
337
|
-
{ level: 'Print', body: 'Line 1' },
|
|
338
|
-
{ level: 'Warning', body: 'Line 2' },
|
|
339
|
-
],
|
|
340
|
-
},
|
|
341
|
-
})
|
|
342
|
-
);
|
|
343
|
-
|
|
344
|
-
client!.send(
|
|
345
|
-
JSON.stringify({
|
|
346
|
-
type: 'output',
|
|
347
|
-
sessionId: ready.sessionId,
|
|
348
|
-
payload: {
|
|
349
|
-
messages: [{ level: 'Error', body: 'Line 3' }],
|
|
350
|
-
},
|
|
351
|
-
})
|
|
352
|
-
);
|
|
353
|
-
|
|
354
|
-
// Complete
|
|
355
|
-
client!.send(
|
|
356
|
-
JSON.stringify({
|
|
357
|
-
type: 'scriptComplete',
|
|
358
|
-
sessionId: ready.sessionId,
|
|
359
|
-
payload: { success: true },
|
|
360
|
-
})
|
|
361
|
-
);
|
|
362
|
-
|
|
363
|
-
const result = await resultPromise;
|
|
364
|
-
expect(result.success).toBe(true);
|
|
365
|
-
expect(result.logs).toContain('Line 1');
|
|
366
|
-
expect(result.logs).toContain('Line 2');
|
|
367
|
-
expect(result.logs).toContain('Line 3');
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
it('calls onOutput for each output entry', async () => {
|
|
371
|
-
const ready = await createReadyServer();
|
|
372
|
-
server = ready.server;
|
|
373
|
-
client = ready.client;
|
|
374
|
-
|
|
375
|
-
const outputEntries: Array<{ level: string; body: string }> = [];
|
|
376
|
-
|
|
377
|
-
const resultPromise = server.executeAsync({
|
|
378
|
-
scriptContent: 'print("test")',
|
|
379
|
-
onOutput: (level, body) => {
|
|
380
|
-
outputEntries.push({ level, body });
|
|
381
|
-
},
|
|
382
|
-
});
|
|
383
|
-
|
|
384
|
-
await new Promise<void>((resolve) => {
|
|
385
|
-
client!.on('message', (raw) => {
|
|
386
|
-
const data = JSON.parse(
|
|
387
|
-
typeof raw === 'string' ? raw : raw.toString('utf-8')
|
|
388
|
-
);
|
|
389
|
-
if (data.type === 'execute') resolve();
|
|
390
|
-
});
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
client!.send(
|
|
394
|
-
JSON.stringify({
|
|
395
|
-
type: 'output',
|
|
396
|
-
sessionId: ready.sessionId,
|
|
397
|
-
payload: {
|
|
398
|
-
messages: [
|
|
399
|
-
{ level: 'Print', body: 'hello' },
|
|
400
|
-
{ level: 'Error', body: 'oops' },
|
|
401
|
-
],
|
|
402
|
-
},
|
|
403
|
-
})
|
|
404
|
-
);
|
|
405
|
-
|
|
406
|
-
client!.send(
|
|
407
|
-
JSON.stringify({
|
|
408
|
-
type: 'scriptComplete',
|
|
409
|
-
sessionId: ready.sessionId,
|
|
410
|
-
payload: { success: true },
|
|
411
|
-
})
|
|
412
|
-
);
|
|
413
|
-
|
|
414
|
-
await resultPromise;
|
|
415
|
-
|
|
416
|
-
expect(outputEntries).toEqual([
|
|
417
|
-
{ level: 'Print', body: 'hello' },
|
|
418
|
-
{ level: 'Error', body: 'oops' },
|
|
419
|
-
]);
|
|
420
|
-
});
|
|
421
|
-
|
|
422
257
|
it('returns failure with error message on script error', async () => {
|
|
423
258
|
const ready = await createReadyServer();
|
|
424
259
|
server = ready.server;
|
|
@@ -473,7 +308,9 @@ describe('StudioBridgeServer', () => {
|
|
|
473
308
|
|
|
474
309
|
const result = await resultPromise;
|
|
475
310
|
expect(result.success).toBe(false);
|
|
476
|
-
expect(result.logs).toContain(
|
|
311
|
+
expect(result.logs).toContain(
|
|
312
|
+
'Plugin disconnected before script completed'
|
|
313
|
+
);
|
|
477
314
|
});
|
|
478
315
|
|
|
479
316
|
it('times out when script takes too long', async () => {
|
|
@@ -528,10 +365,6 @@ describe('StudioBridgeServer', () => {
|
|
|
528
365
|
});
|
|
529
366
|
});
|
|
530
367
|
|
|
531
|
-
// -----------------------------------------------------------------------
|
|
532
|
-
// Multi-execution (reuse)
|
|
533
|
-
// -----------------------------------------------------------------------
|
|
534
|
-
|
|
535
368
|
describe('multi-execution', () => {
|
|
536
369
|
it('supports executing multiple scripts on the same session', async () => {
|
|
537
370
|
const ready = await createReadyServer();
|
|
@@ -577,63 +410,8 @@ describe('StudioBridgeServer', () => {
|
|
|
577
410
|
const r3 = await runOnce('print("third")');
|
|
578
411
|
expect(r3.success).toBe(true);
|
|
579
412
|
});
|
|
580
|
-
|
|
581
|
-
it('isolates logs between executions', async () => {
|
|
582
|
-
const ready = await createReadyServer();
|
|
583
|
-
server = ready.server;
|
|
584
|
-
client = ready.client;
|
|
585
|
-
|
|
586
|
-
const runWithOutput = async (outputBody: string) => {
|
|
587
|
-
const resultPromise = server!.executeAsync({
|
|
588
|
-
scriptContent: 'print("x")',
|
|
589
|
-
});
|
|
590
|
-
|
|
591
|
-
await new Promise<void>((resolve) => {
|
|
592
|
-
const handler = (raw: any) => {
|
|
593
|
-
const data = JSON.parse(
|
|
594
|
-
typeof raw === 'string' ? raw : raw.toString('utf-8')
|
|
595
|
-
);
|
|
596
|
-
if (data.type === 'execute') {
|
|
597
|
-
client!.off('message', handler);
|
|
598
|
-
resolve();
|
|
599
|
-
}
|
|
600
|
-
};
|
|
601
|
-
client!.on('message', handler);
|
|
602
|
-
});
|
|
603
|
-
|
|
604
|
-
client!.send(
|
|
605
|
-
JSON.stringify({
|
|
606
|
-
type: 'output',
|
|
607
|
-
sessionId: ready.sessionId,
|
|
608
|
-
payload: { messages: [{ level: 'Print', body: outputBody }] },
|
|
609
|
-
})
|
|
610
|
-
);
|
|
611
|
-
|
|
612
|
-
client!.send(
|
|
613
|
-
JSON.stringify({
|
|
614
|
-
type: 'scriptComplete',
|
|
615
|
-
sessionId: ready.sessionId,
|
|
616
|
-
payload: { success: true },
|
|
617
|
-
})
|
|
618
|
-
);
|
|
619
|
-
|
|
620
|
-
return resultPromise;
|
|
621
|
-
};
|
|
622
|
-
|
|
623
|
-
const r1 = await runWithOutput('output-from-first');
|
|
624
|
-
const r2 = await runWithOutput('output-from-second');
|
|
625
|
-
|
|
626
|
-
expect(r1.logs).toBe('output-from-first');
|
|
627
|
-
expect(r1.logs).not.toContain('output-from-second');
|
|
628
|
-
expect(r2.logs).toBe('output-from-second');
|
|
629
|
-
expect(r2.logs).not.toContain('output-from-first');
|
|
630
|
-
});
|
|
631
413
|
});
|
|
632
414
|
|
|
633
|
-
// -----------------------------------------------------------------------
|
|
634
|
-
// Phase callbacks
|
|
635
|
-
// -----------------------------------------------------------------------
|
|
636
|
-
|
|
637
415
|
describe('onPhase', () => {
|
|
638
416
|
it('fires phase callbacks in order during lifecycle', async () => {
|
|
639
417
|
const phases: StudioBridgePhase[] = [];
|
|
@@ -684,10 +462,6 @@ describe('StudioBridgeServer', () => {
|
|
|
684
462
|
});
|
|
685
463
|
});
|
|
686
464
|
|
|
687
|
-
// -----------------------------------------------------------------------
|
|
688
|
-
// Cleanup / stopAsync
|
|
689
|
-
// -----------------------------------------------------------------------
|
|
690
|
-
|
|
691
465
|
describe('stopAsync', () => {
|
|
692
466
|
it('sends shutdown message with sessionId to connected client', async () => {
|
|
693
467
|
const ready = await createReadyServer();
|
|
@@ -702,7 +476,11 @@ describe('StudioBridgeServer', () => {
|
|
|
702
476
|
await server.stopAsync();
|
|
703
477
|
|
|
704
478
|
expect(sendSpy).toHaveBeenCalledWith(
|
|
705
|
-
JSON.stringify({
|
|
479
|
+
JSON.stringify({
|
|
480
|
+
type: 'shutdown',
|
|
481
|
+
sessionId: ready.sessionId,
|
|
482
|
+
payload: {},
|
|
483
|
+
})
|
|
706
484
|
);
|
|
707
485
|
});
|
|
708
486
|
|
|
@@ -712,4 +490,264 @@ describe('StudioBridgeServer', () => {
|
|
|
712
490
|
await server.stopAsync();
|
|
713
491
|
});
|
|
714
492
|
});
|
|
493
|
+
|
|
494
|
+
describe('heartbeat', () => {
|
|
495
|
+
it('silently accepts heartbeat messages after handshake', async () => {
|
|
496
|
+
const ready = await createReadyServer();
|
|
497
|
+
server = ready.server;
|
|
498
|
+
client = ready.client;
|
|
499
|
+
|
|
500
|
+
// Send a heartbeat message
|
|
501
|
+
client.send(
|
|
502
|
+
JSON.stringify({
|
|
503
|
+
type: 'heartbeat',
|
|
504
|
+
sessionId: ready.sessionId,
|
|
505
|
+
payload: {
|
|
506
|
+
uptimeMs: 5000,
|
|
507
|
+
state: 'Edit',
|
|
508
|
+
pendingRequests: 0,
|
|
509
|
+
},
|
|
510
|
+
})
|
|
511
|
+
);
|
|
512
|
+
|
|
513
|
+
// Give it time to process
|
|
514
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
515
|
+
|
|
516
|
+
// Verify the server recorded the heartbeat
|
|
517
|
+
const lastHb = (server as any)._lastHeartbeatTimestamp;
|
|
518
|
+
expect(lastHb).toBeGreaterThan(0);
|
|
519
|
+
});
|
|
520
|
+
|
|
521
|
+
it('does not interfere with script execution', async () => {
|
|
522
|
+
const ready = await createReadyServer();
|
|
523
|
+
server = ready.server;
|
|
524
|
+
client = ready.client;
|
|
525
|
+
|
|
526
|
+
const resultPromise = server.executeAsync({
|
|
527
|
+
scriptContent: 'print("test")',
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
await new Promise<void>((resolve) => {
|
|
531
|
+
client!.on('message', (raw) => {
|
|
532
|
+
const data = JSON.parse(
|
|
533
|
+
typeof raw === 'string' ? raw : raw.toString('utf-8')
|
|
534
|
+
);
|
|
535
|
+
if (data.type === 'execute') resolve();
|
|
536
|
+
});
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
// Send a heartbeat during execution
|
|
540
|
+
client!.send(
|
|
541
|
+
JSON.stringify({
|
|
542
|
+
type: 'heartbeat',
|
|
543
|
+
sessionId: ready.sessionId,
|
|
544
|
+
payload: {
|
|
545
|
+
uptimeMs: 10000,
|
|
546
|
+
state: 'Edit',
|
|
547
|
+
pendingRequests: 1,
|
|
548
|
+
},
|
|
549
|
+
})
|
|
550
|
+
);
|
|
551
|
+
|
|
552
|
+
// Then complete the script
|
|
553
|
+
client!.send(
|
|
554
|
+
JSON.stringify({
|
|
555
|
+
type: 'scriptComplete',
|
|
556
|
+
sessionId: ready.sessionId,
|
|
557
|
+
payload: { success: true },
|
|
558
|
+
})
|
|
559
|
+
);
|
|
560
|
+
|
|
561
|
+
const result = await resultPromise;
|
|
562
|
+
expect(result.success).toBe(true);
|
|
563
|
+
});
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
describe('performActionAsync', () => {
|
|
567
|
+
/**
|
|
568
|
+
* Connect with v2 register, start the server, and return a ready state.
|
|
569
|
+
*/
|
|
570
|
+
async function createV2ReadyServer(options?: {
|
|
571
|
+
sessionId?: string;
|
|
572
|
+
capabilities?: string[];
|
|
573
|
+
}) {
|
|
574
|
+
const sessionId = options?.sessionId ?? 'v2-action-session';
|
|
575
|
+
const capabilities = options?.capabilities ?? [
|
|
576
|
+
'execute',
|
|
577
|
+
'queryState',
|
|
578
|
+
'captureScreenshot',
|
|
579
|
+
];
|
|
580
|
+
|
|
581
|
+
const srv = new StudioBridgeServer({
|
|
582
|
+
placePath: '/fake/place.rbxl',
|
|
583
|
+
sessionId,
|
|
584
|
+
timeoutMs: 5_000,
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
const startPromise = srv.startAsync();
|
|
588
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
589
|
+
const port: number = (srv as any)._port;
|
|
590
|
+
|
|
591
|
+
const ws = new WebSocket(`ws://localhost:${port}/${sessionId}`);
|
|
592
|
+
await new Promise<void>((resolve, reject) => {
|
|
593
|
+
ws.on('open', resolve);
|
|
594
|
+
ws.on('error', reject);
|
|
595
|
+
});
|
|
596
|
+
|
|
597
|
+
ws.send(
|
|
598
|
+
JSON.stringify({
|
|
599
|
+
type: 'register',
|
|
600
|
+
sessionId,
|
|
601
|
+
payload: {
|
|
602
|
+
pluginVersion: '2.0.0',
|
|
603
|
+
instanceId: 'inst-action',
|
|
604
|
+
placeName: 'ActionTestPlace',
|
|
605
|
+
state: 'Edit',
|
|
606
|
+
capabilities,
|
|
607
|
+
},
|
|
608
|
+
})
|
|
609
|
+
);
|
|
610
|
+
|
|
611
|
+
await startPromise;
|
|
612
|
+
|
|
613
|
+
return { server: srv, client: ws, port, sessionId };
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
it('sends queryState action and resolves with stateResult', async () => {
|
|
617
|
+
const ready = await createV2ReadyServer();
|
|
618
|
+
server = ready.server;
|
|
619
|
+
client = ready.client;
|
|
620
|
+
|
|
621
|
+
// Listen for the queryState action from the server
|
|
622
|
+
const actionPromise = new Promise<Record<string, unknown>>((resolve) => {
|
|
623
|
+
client!.on('message', (raw) => {
|
|
624
|
+
const data = JSON.parse(
|
|
625
|
+
typeof raw === 'string' ? raw : raw.toString('utf-8')
|
|
626
|
+
);
|
|
627
|
+
if (data.type === 'queryState') {
|
|
628
|
+
resolve(data);
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
// Perform the action
|
|
634
|
+
const resultPromise = server.performActionAsync({
|
|
635
|
+
type: 'queryState',
|
|
636
|
+
payload: {},
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
// Wait for the queryState message to arrive at the mock plugin
|
|
640
|
+
const queryMsg = await actionPromise;
|
|
641
|
+
expect(queryMsg.type).toBe('queryState');
|
|
642
|
+
expect(queryMsg.sessionId).toBe(ready.sessionId);
|
|
643
|
+
expect(typeof queryMsg.requestId).toBe('string');
|
|
644
|
+
|
|
645
|
+
// Respond from the mock plugin
|
|
646
|
+
client!.send(
|
|
647
|
+
JSON.stringify({
|
|
648
|
+
type: 'stateResult',
|
|
649
|
+
sessionId: ready.sessionId,
|
|
650
|
+
requestId: queryMsg.requestId,
|
|
651
|
+
payload: {
|
|
652
|
+
state: 'Edit',
|
|
653
|
+
placeId: 12345,
|
|
654
|
+
placeName: 'ActionTestPlace',
|
|
655
|
+
gameId: 67890,
|
|
656
|
+
},
|
|
657
|
+
})
|
|
658
|
+
);
|
|
659
|
+
|
|
660
|
+
const result = await resultPromise;
|
|
661
|
+
expect(result.type).toBe('stateResult');
|
|
662
|
+
expect((result as any).payload.state).toBe('Edit');
|
|
663
|
+
expect((result as any).payload.placeId).toBe(12345);
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
it('rejects when plugin does not support requested capability', async () => {
|
|
667
|
+
// Connect with only 'execute' capability — no 'queryState'
|
|
668
|
+
const ready = await createV2ReadyServer({ capabilities: ['execute'] });
|
|
669
|
+
server = ready.server;
|
|
670
|
+
client = ready.client;
|
|
671
|
+
|
|
672
|
+
await expect(
|
|
673
|
+
server.performActionAsync({ type: 'queryState', payload: {} })
|
|
674
|
+
).rejects.toThrow('Plugin does not support capability: queryState');
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
it('rejects when server is not in ready state', async () => {
|
|
678
|
+
server = new StudioBridgeServer({ placePath: '/fake/place.rbxl' });
|
|
679
|
+
|
|
680
|
+
await expect(
|
|
681
|
+
server.performActionAsync({ type: 'queryState', payload: {} })
|
|
682
|
+
).rejects.toThrow(
|
|
683
|
+
"Cannot perform action: expected state 'ready', got 'idle'"
|
|
684
|
+
);
|
|
685
|
+
});
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
describe('health endpoint', () => {
|
|
689
|
+
it('GET /health returns 200 with correct JSON shape', async () => {
|
|
690
|
+
const ready = await createReadyServer({ sessionId: 'health-session' });
|
|
691
|
+
server = ready.server;
|
|
692
|
+
client = ready.client;
|
|
693
|
+
|
|
694
|
+
const res = await fetch(`http://localhost:${ready.port}/health`);
|
|
695
|
+
expect(res.status).toBe(200);
|
|
696
|
+
expect(res.headers.get('content-type')).toBe('application/json');
|
|
697
|
+
|
|
698
|
+
const body = (await res.json()) as Record<string, unknown>;
|
|
699
|
+
expect(body.status).toBe('ok');
|
|
700
|
+
expect(body.sessionId).toBe('health-session');
|
|
701
|
+
expect(body.port).toBe(ready.port);
|
|
702
|
+
expect(typeof body.serverVersion).toBe('string');
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
it('GET /other returns 404', async () => {
|
|
706
|
+
const ready = await createReadyServer();
|
|
707
|
+
server = ready.server;
|
|
708
|
+
client = ready.client;
|
|
709
|
+
|
|
710
|
+
const res = await fetch(`http://localhost:${ready.port}/other`);
|
|
711
|
+
expect(res.status).toBe(404);
|
|
712
|
+
|
|
713
|
+
const body = await res.text();
|
|
714
|
+
expect(body).toBe('Not Found');
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
it('health endpoint is available immediately after startAsync', async () => {
|
|
718
|
+
const sessionId = 'immediate-health';
|
|
719
|
+
server = new StudioBridgeServer({
|
|
720
|
+
placePath: '/fake/place.rbxl',
|
|
721
|
+
sessionId,
|
|
722
|
+
timeoutMs: 5_000,
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
const startPromise = server.startAsync();
|
|
726
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
727
|
+
const port: number = (server as any)._port;
|
|
728
|
+
|
|
729
|
+
// Health should be available even before handshake completes
|
|
730
|
+
const res = await fetch(`http://localhost:${port}/health`);
|
|
731
|
+
expect(res.status).toBe(200);
|
|
732
|
+
|
|
733
|
+
const body = (await res.json()) as Record<string, unknown>;
|
|
734
|
+
expect(body.status).toBe('ok');
|
|
735
|
+
expect(body.sessionId).toBe(sessionId);
|
|
736
|
+
|
|
737
|
+
// Complete the handshake so startAsync resolves
|
|
738
|
+
client = await connectAndHandshake(port, sessionId);
|
|
739
|
+
await startPromise;
|
|
740
|
+
});
|
|
741
|
+
|
|
742
|
+
it('WebSocket upgrades to correct path still work after adding health endpoint', async () => {
|
|
743
|
+
const ready = await createReadyServer({ sessionId: 'ws-with-health' });
|
|
744
|
+
server = ready.server;
|
|
745
|
+
client = ready.client;
|
|
746
|
+
|
|
747
|
+
// If we got here, the WebSocket handshake succeeded through the HTTP server
|
|
748
|
+
// Verify health also works
|
|
749
|
+
const res = await fetch(`http://localhost:${ready.port}/health`);
|
|
750
|
+
expect(res.status).toBe(200);
|
|
751
|
+
});
|
|
752
|
+
});
|
|
715
753
|
});
|