@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
|
@@ -0,0 +1,773 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for BridgeConnection -- validates role detection, connection
|
|
3
|
+
* lifecycle, session listing, resolution, waiting, and event forwarding.
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, expect, afterEach, vi } from 'vitest';
|
|
6
|
+
import { WebSocket } from 'ws';
|
|
7
|
+
import { BridgeConnection } from './bridge-connection.js';
|
|
8
|
+
import { SessionNotFoundError, ContextNotFoundError } from './types.js';
|
|
9
|
+
function connectPlugin(port) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
const ws = new WebSocket(`ws://localhost:${port}/plugin`);
|
|
12
|
+
ws.on('open', () => resolve(ws));
|
|
13
|
+
ws.on('error', reject);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
async function performRegisterHandshake(port, sessionId, options) {
|
|
17
|
+
const ws = await connectPlugin(port);
|
|
18
|
+
ws.send(JSON.stringify({
|
|
19
|
+
type: 'register',
|
|
20
|
+
sessionId,
|
|
21
|
+
payload: {
|
|
22
|
+
pluginVersion: '1.0.0',
|
|
23
|
+
instanceId: options?.instanceId ?? 'inst-1',
|
|
24
|
+
placeName: options?.placeName ?? 'TestPlace',
|
|
25
|
+
state: options?.state ?? 'Edit',
|
|
26
|
+
capabilities: options?.capabilities ?? ['execute', 'queryState'],
|
|
27
|
+
},
|
|
28
|
+
}));
|
|
29
|
+
// Allow the host to process the register message
|
|
30
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
31
|
+
return { ws };
|
|
32
|
+
}
|
|
33
|
+
describe('BridgeConnection', () => {
|
|
34
|
+
const openClients = [];
|
|
35
|
+
const connections = [];
|
|
36
|
+
afterEach(async () => {
|
|
37
|
+
for (const ws of openClients) {
|
|
38
|
+
if (ws.readyState === WebSocket.OPEN ||
|
|
39
|
+
ws.readyState === WebSocket.CONNECTING) {
|
|
40
|
+
ws.close();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
openClients.length = 0;
|
|
44
|
+
for (const conn of [...connections].reverse()) {
|
|
45
|
+
await conn.disconnectAsync();
|
|
46
|
+
}
|
|
47
|
+
connections.length = 0;
|
|
48
|
+
});
|
|
49
|
+
describe('connectAsync', () => {
|
|
50
|
+
it('becomes host on unused ephemeral port', async () => {
|
|
51
|
+
const conn = await BridgeConnection.connectAsync({
|
|
52
|
+
port: 0,
|
|
53
|
+
keepAlive: true,
|
|
54
|
+
});
|
|
55
|
+
connections.push(conn);
|
|
56
|
+
expect(conn.role).toBe('host');
|
|
57
|
+
expect(conn.isConnected).toBe(true);
|
|
58
|
+
expect(conn.port).toBeGreaterThan(0);
|
|
59
|
+
});
|
|
60
|
+
it('accepts plugin connections as host', async () => {
|
|
61
|
+
const conn = await BridgeConnection.connectAsync({
|
|
62
|
+
port: 0,
|
|
63
|
+
keepAlive: true,
|
|
64
|
+
});
|
|
65
|
+
connections.push(conn);
|
|
66
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-1');
|
|
67
|
+
openClients.push(ws);
|
|
68
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
69
|
+
expect(conn.listSessions()).toHaveLength(1);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
describe('disconnectAsync', () => {
|
|
73
|
+
it('sets isConnected to false', async () => {
|
|
74
|
+
const conn = await BridgeConnection.connectAsync({
|
|
75
|
+
port: 0,
|
|
76
|
+
keepAlive: true,
|
|
77
|
+
});
|
|
78
|
+
connections.push(conn);
|
|
79
|
+
expect(conn.isConnected).toBe(true);
|
|
80
|
+
await conn.disconnectAsync();
|
|
81
|
+
connections.length = 0;
|
|
82
|
+
expect(conn.isConnected).toBe(false);
|
|
83
|
+
});
|
|
84
|
+
it('is idempotent', async () => {
|
|
85
|
+
const conn = await BridgeConnection.connectAsync({
|
|
86
|
+
port: 0,
|
|
87
|
+
keepAlive: true,
|
|
88
|
+
});
|
|
89
|
+
await conn.disconnectAsync();
|
|
90
|
+
await conn.disconnectAsync();
|
|
91
|
+
expect(conn.isConnected).toBe(false);
|
|
92
|
+
});
|
|
93
|
+
it('cleans up host resources', async () => {
|
|
94
|
+
const conn = await BridgeConnection.connectAsync({
|
|
95
|
+
port: 0,
|
|
96
|
+
keepAlive: true,
|
|
97
|
+
});
|
|
98
|
+
connections.push(conn);
|
|
99
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-1');
|
|
100
|
+
openClients.push(ws);
|
|
101
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
102
|
+
expect(conn.listSessions()).toHaveLength(1);
|
|
103
|
+
await conn.disconnectAsync();
|
|
104
|
+
connections.length = 0;
|
|
105
|
+
expect(conn.isConnected).toBe(false);
|
|
106
|
+
expect(conn.listSessions()).toEqual([]);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe('listSessions', () => {
|
|
110
|
+
it('returns empty list when no plugins connected', async () => {
|
|
111
|
+
const conn = await BridgeConnection.connectAsync({
|
|
112
|
+
port: 0,
|
|
113
|
+
keepAlive: true,
|
|
114
|
+
});
|
|
115
|
+
connections.push(conn);
|
|
116
|
+
expect(conn.listSessions()).toEqual([]);
|
|
117
|
+
});
|
|
118
|
+
it('returns sessions from connected plugins', async () => {
|
|
119
|
+
const conn = await BridgeConnection.connectAsync({
|
|
120
|
+
port: 0,
|
|
121
|
+
keepAlive: true,
|
|
122
|
+
});
|
|
123
|
+
connections.push(conn);
|
|
124
|
+
const { ws: ws1 } = await performRegisterHandshake(conn.port, 'session-a', {
|
|
125
|
+
instanceId: 'inst-A',
|
|
126
|
+
placeName: 'PlaceA',
|
|
127
|
+
});
|
|
128
|
+
openClients.push(ws1);
|
|
129
|
+
const { ws: ws2 } = await performRegisterHandshake(conn.port, 'session-b', {
|
|
130
|
+
instanceId: 'inst-B',
|
|
131
|
+
placeName: 'PlaceB',
|
|
132
|
+
});
|
|
133
|
+
openClients.push(ws2);
|
|
134
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
135
|
+
const sessions = conn.listSessions();
|
|
136
|
+
expect(sessions).toHaveLength(2);
|
|
137
|
+
expect(sessions.map((s) => s.sessionId).sort()).toEqual([
|
|
138
|
+
'session-a',
|
|
139
|
+
'session-b',
|
|
140
|
+
]);
|
|
141
|
+
});
|
|
142
|
+
it('removes session when plugin disconnects', async () => {
|
|
143
|
+
const conn = await BridgeConnection.connectAsync({
|
|
144
|
+
port: 0,
|
|
145
|
+
keepAlive: true,
|
|
146
|
+
});
|
|
147
|
+
connections.push(conn);
|
|
148
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-dc');
|
|
149
|
+
openClients.push(ws);
|
|
150
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
151
|
+
expect(conn.listSessions()).toHaveLength(1);
|
|
152
|
+
ws.close();
|
|
153
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
154
|
+
expect(conn.listSessions()).toHaveLength(0);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
describe('listInstances', () => {
|
|
158
|
+
it('returns empty list when no plugins connected', async () => {
|
|
159
|
+
const conn = await BridgeConnection.connectAsync({
|
|
160
|
+
port: 0,
|
|
161
|
+
keepAlive: true,
|
|
162
|
+
});
|
|
163
|
+
connections.push(conn);
|
|
164
|
+
expect(conn.listInstances()).toEqual([]);
|
|
165
|
+
});
|
|
166
|
+
it('groups sessions by instanceId', async () => {
|
|
167
|
+
const conn = await BridgeConnection.connectAsync({
|
|
168
|
+
port: 0,
|
|
169
|
+
keepAlive: true,
|
|
170
|
+
});
|
|
171
|
+
connections.push(conn);
|
|
172
|
+
// Two sessions from the same instance (edit + server contexts)
|
|
173
|
+
// Context is derived from state: 'Edit' -> 'edit', 'Server' -> 'server'
|
|
174
|
+
const { ws: ws1 } = await performRegisterHandshake(conn.port, 'session-edit', {
|
|
175
|
+
instanceId: 'inst-A',
|
|
176
|
+
placeName: 'PlaceA',
|
|
177
|
+
state: 'Edit',
|
|
178
|
+
});
|
|
179
|
+
openClients.push(ws1);
|
|
180
|
+
const { ws: ws2 } = await performRegisterHandshake(conn.port, 'session-server', {
|
|
181
|
+
instanceId: 'inst-A',
|
|
182
|
+
placeName: 'PlaceA',
|
|
183
|
+
state: 'Server',
|
|
184
|
+
});
|
|
185
|
+
openClients.push(ws2);
|
|
186
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
187
|
+
const instances = conn.listInstances();
|
|
188
|
+
expect(instances).toHaveLength(1);
|
|
189
|
+
expect(instances[0].instanceId).toBe('inst-A');
|
|
190
|
+
expect(instances[0].contexts.sort()).toEqual(['edit', 'server']);
|
|
191
|
+
});
|
|
192
|
+
it('separates different instances', async () => {
|
|
193
|
+
const conn = await BridgeConnection.connectAsync({
|
|
194
|
+
port: 0,
|
|
195
|
+
keepAlive: true,
|
|
196
|
+
});
|
|
197
|
+
connections.push(conn);
|
|
198
|
+
const { ws: ws1 } = await performRegisterHandshake(conn.port, 'session-1', {
|
|
199
|
+
instanceId: 'inst-A',
|
|
200
|
+
});
|
|
201
|
+
openClients.push(ws1);
|
|
202
|
+
const { ws: ws2 } = await performRegisterHandshake(conn.port, 'session-2', {
|
|
203
|
+
instanceId: 'inst-B',
|
|
204
|
+
});
|
|
205
|
+
openClients.push(ws2);
|
|
206
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
207
|
+
const instances = conn.listInstances();
|
|
208
|
+
expect(instances).toHaveLength(2);
|
|
209
|
+
expect(instances.map((i) => i.instanceId).sort()).toEqual([
|
|
210
|
+
'inst-A',
|
|
211
|
+
'inst-B',
|
|
212
|
+
]);
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
describe('getSession', () => {
|
|
216
|
+
it('returns a BridgeSession for a known session', async () => {
|
|
217
|
+
const conn = await BridgeConnection.connectAsync({
|
|
218
|
+
port: 0,
|
|
219
|
+
keepAlive: true,
|
|
220
|
+
});
|
|
221
|
+
connections.push(conn);
|
|
222
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-x', {
|
|
223
|
+
instanceId: 'inst-1',
|
|
224
|
+
placeName: 'TestPlace',
|
|
225
|
+
});
|
|
226
|
+
openClients.push(ws);
|
|
227
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
228
|
+
const session = conn.getSession('session-x');
|
|
229
|
+
expect(session).toBeDefined();
|
|
230
|
+
expect(session.info.sessionId).toBe('session-x');
|
|
231
|
+
});
|
|
232
|
+
it('returns undefined for unknown session', async () => {
|
|
233
|
+
const conn = await BridgeConnection.connectAsync({
|
|
234
|
+
port: 0,
|
|
235
|
+
keepAlive: true,
|
|
236
|
+
});
|
|
237
|
+
connections.push(conn);
|
|
238
|
+
expect(conn.getSession('nonexistent')).toBeUndefined();
|
|
239
|
+
});
|
|
240
|
+
it('returns undefined after plugin disconnects', async () => {
|
|
241
|
+
const conn = await BridgeConnection.connectAsync({
|
|
242
|
+
port: 0,
|
|
243
|
+
keepAlive: true,
|
|
244
|
+
});
|
|
245
|
+
connections.push(conn);
|
|
246
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-gone');
|
|
247
|
+
openClients.push(ws);
|
|
248
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
249
|
+
expect(conn.getSession('session-gone')).toBeDefined();
|
|
250
|
+
ws.close();
|
|
251
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
252
|
+
expect(conn.getSession('session-gone')).toBeUndefined();
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
describe('resolveSession', () => {
|
|
256
|
+
it('throws "No sessions connected" when no sessions exist', async () => {
|
|
257
|
+
const conn = await BridgeConnection.connectAsync({
|
|
258
|
+
port: 0,
|
|
259
|
+
keepAlive: true,
|
|
260
|
+
});
|
|
261
|
+
connections.push(conn);
|
|
262
|
+
// resolveSession waits up to 5s for a plugin to connect when acting as
|
|
263
|
+
// host with no sessions, so we need a longer test timeout
|
|
264
|
+
await expect(conn.resolveSessionAsync()).rejects.toThrow(SessionNotFoundError);
|
|
265
|
+
await expect(conn.resolveSessionAsync()).rejects.toThrow('No sessions connected');
|
|
266
|
+
}, 15_000);
|
|
267
|
+
it('returns the only session automatically', async () => {
|
|
268
|
+
const conn = await BridgeConnection.connectAsync({
|
|
269
|
+
port: 0,
|
|
270
|
+
keepAlive: true,
|
|
271
|
+
});
|
|
272
|
+
connections.push(conn);
|
|
273
|
+
const { ws } = await performRegisterHandshake(conn.port, 'only-session', {
|
|
274
|
+
instanceId: 'inst-1',
|
|
275
|
+
});
|
|
276
|
+
openClients.push(ws);
|
|
277
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
278
|
+
const session = await conn.resolveSessionAsync();
|
|
279
|
+
expect(session.info.sessionId).toBe('only-session');
|
|
280
|
+
});
|
|
281
|
+
it('throws with instance list when multiple instances exist', async () => {
|
|
282
|
+
const conn = await BridgeConnection.connectAsync({
|
|
283
|
+
port: 0,
|
|
284
|
+
keepAlive: true,
|
|
285
|
+
});
|
|
286
|
+
connections.push(conn);
|
|
287
|
+
const { ws: ws1 } = await performRegisterHandshake(conn.port, 'session-1', {
|
|
288
|
+
instanceId: 'inst-A',
|
|
289
|
+
placeName: 'PlaceA',
|
|
290
|
+
});
|
|
291
|
+
openClients.push(ws1);
|
|
292
|
+
const { ws: ws2 } = await performRegisterHandshake(conn.port, 'session-2', {
|
|
293
|
+
instanceId: 'inst-B',
|
|
294
|
+
placeName: 'PlaceB',
|
|
295
|
+
});
|
|
296
|
+
openClients.push(ws2);
|
|
297
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
298
|
+
await expect(conn.resolveSessionAsync()).rejects.toThrow(SessionNotFoundError);
|
|
299
|
+
await expect(conn.resolveSessionAsync()).rejects.toThrow('Multiple Studio instances');
|
|
300
|
+
});
|
|
301
|
+
it('returns specific session by sessionId', async () => {
|
|
302
|
+
const conn = await BridgeConnection.connectAsync({
|
|
303
|
+
port: 0,
|
|
304
|
+
keepAlive: true,
|
|
305
|
+
});
|
|
306
|
+
connections.push(conn);
|
|
307
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-abc', {
|
|
308
|
+
instanceId: 'inst-1',
|
|
309
|
+
});
|
|
310
|
+
openClients.push(ws);
|
|
311
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
312
|
+
const session = await conn.resolveSessionAsync('session-abc');
|
|
313
|
+
expect(session.info.sessionId).toBe('session-abc');
|
|
314
|
+
});
|
|
315
|
+
it('throws SessionNotFoundError for unknown sessionId', async () => {
|
|
316
|
+
const conn = await BridgeConnection.connectAsync({
|
|
317
|
+
port: 0,
|
|
318
|
+
keepAlive: true,
|
|
319
|
+
});
|
|
320
|
+
connections.push(conn);
|
|
321
|
+
await expect(conn.resolveSessionAsync('nonexistent')).rejects.toThrow(SessionNotFoundError);
|
|
322
|
+
await expect(conn.resolveSessionAsync('nonexistent')).rejects.toThrow("Session 'nonexistent' not found");
|
|
323
|
+
});
|
|
324
|
+
it('returns Edit context by default when multiple contexts exist', async () => {
|
|
325
|
+
const conn = await BridgeConnection.connectAsync({
|
|
326
|
+
port: 0,
|
|
327
|
+
keepAlive: true,
|
|
328
|
+
});
|
|
329
|
+
connections.push(conn);
|
|
330
|
+
// Simulate Play mode: edit + server + client contexts
|
|
331
|
+
const { ws: ws1 } = await performRegisterHandshake(conn.port, 'edit-session', {
|
|
332
|
+
instanceId: 'inst-1',
|
|
333
|
+
state: 'Edit',
|
|
334
|
+
});
|
|
335
|
+
openClients.push(ws1);
|
|
336
|
+
const { ws: ws2 } = await performRegisterHandshake(conn.port, 'server-session', {
|
|
337
|
+
instanceId: 'inst-1',
|
|
338
|
+
state: 'Server',
|
|
339
|
+
});
|
|
340
|
+
openClients.push(ws2);
|
|
341
|
+
const { ws: ws3 } = await performRegisterHandshake(conn.port, 'client-session', {
|
|
342
|
+
instanceId: 'inst-1',
|
|
343
|
+
state: 'Client',
|
|
344
|
+
});
|
|
345
|
+
openClients.push(ws3);
|
|
346
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
347
|
+
// Should return the Edit context by default
|
|
348
|
+
const session = await conn.resolveSessionAsync();
|
|
349
|
+
expect(session.info.sessionId).toBe('edit-session');
|
|
350
|
+
expect(session.context).toBe('edit');
|
|
351
|
+
});
|
|
352
|
+
it('returns specific context when requested', async () => {
|
|
353
|
+
const conn = await BridgeConnection.connectAsync({
|
|
354
|
+
port: 0,
|
|
355
|
+
keepAlive: true,
|
|
356
|
+
});
|
|
357
|
+
connections.push(conn);
|
|
358
|
+
const { ws: ws1 } = await performRegisterHandshake(conn.port, 'edit-s', {
|
|
359
|
+
instanceId: 'inst-1',
|
|
360
|
+
state: 'Edit',
|
|
361
|
+
});
|
|
362
|
+
openClients.push(ws1);
|
|
363
|
+
const { ws: ws2 } = await performRegisterHandshake(conn.port, 'server-s', {
|
|
364
|
+
instanceId: 'inst-1',
|
|
365
|
+
state: 'Server',
|
|
366
|
+
});
|
|
367
|
+
openClients.push(ws2);
|
|
368
|
+
const { ws: ws3 } = await performRegisterHandshake(conn.port, 'client-s', {
|
|
369
|
+
instanceId: 'inst-1',
|
|
370
|
+
state: 'Client',
|
|
371
|
+
});
|
|
372
|
+
openClients.push(ws3);
|
|
373
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
374
|
+
const serverSession = await conn.resolveSessionAsync(undefined, 'server');
|
|
375
|
+
expect(serverSession.info.sessionId).toBe('server-s');
|
|
376
|
+
expect(serverSession.context).toBe('server');
|
|
377
|
+
const clientSession = await conn.resolveSessionAsync(undefined, 'client');
|
|
378
|
+
expect(clientSession.info.sessionId).toBe('client-s');
|
|
379
|
+
expect(clientSession.context).toBe('client');
|
|
380
|
+
});
|
|
381
|
+
it('throws ContextNotFoundError for unavailable context', async () => {
|
|
382
|
+
const conn = await BridgeConnection.connectAsync({
|
|
383
|
+
port: 0,
|
|
384
|
+
keepAlive: true,
|
|
385
|
+
});
|
|
386
|
+
connections.push(conn);
|
|
387
|
+
// Only edit context connected
|
|
388
|
+
const { ws } = await performRegisterHandshake(conn.port, 'edit-only', {
|
|
389
|
+
instanceId: 'inst-1',
|
|
390
|
+
state: 'Edit',
|
|
391
|
+
});
|
|
392
|
+
openClients.push(ws);
|
|
393
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
394
|
+
await expect(conn.resolveSessionAsync(undefined, 'server')).rejects.toThrow(ContextNotFoundError);
|
|
395
|
+
});
|
|
396
|
+
it('resolves by instanceId', async () => {
|
|
397
|
+
const conn = await BridgeConnection.connectAsync({
|
|
398
|
+
port: 0,
|
|
399
|
+
keepAlive: true,
|
|
400
|
+
});
|
|
401
|
+
connections.push(conn);
|
|
402
|
+
const { ws: ws1 } = await performRegisterHandshake(conn.port, 'session-A', {
|
|
403
|
+
instanceId: 'inst-A',
|
|
404
|
+
placeName: 'PlaceA',
|
|
405
|
+
});
|
|
406
|
+
openClients.push(ws1);
|
|
407
|
+
const { ws: ws2 } = await performRegisterHandshake(conn.port, 'session-B', {
|
|
408
|
+
instanceId: 'inst-B',
|
|
409
|
+
placeName: 'PlaceB',
|
|
410
|
+
});
|
|
411
|
+
openClients.push(ws2);
|
|
412
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
413
|
+
const session = await conn.resolveSessionAsync(undefined, undefined, 'inst-B');
|
|
414
|
+
expect(session.info.sessionId).toBe('session-B');
|
|
415
|
+
});
|
|
416
|
+
it('resolves by instanceId and context', async () => {
|
|
417
|
+
const conn = await BridgeConnection.connectAsync({
|
|
418
|
+
port: 0,
|
|
419
|
+
keepAlive: true,
|
|
420
|
+
});
|
|
421
|
+
connections.push(conn);
|
|
422
|
+
const { ws: ws1 } = await performRegisterHandshake(conn.port, 'edit-s', {
|
|
423
|
+
instanceId: 'inst-1',
|
|
424
|
+
state: 'Edit',
|
|
425
|
+
});
|
|
426
|
+
openClients.push(ws1);
|
|
427
|
+
const { ws: ws2 } = await performRegisterHandshake(conn.port, 'server-s', {
|
|
428
|
+
instanceId: 'inst-1',
|
|
429
|
+
state: 'Server',
|
|
430
|
+
});
|
|
431
|
+
openClients.push(ws2);
|
|
432
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
433
|
+
const session = await conn.resolveSessionAsync(undefined, 'server', 'inst-1');
|
|
434
|
+
expect(session.info.sessionId).toBe('server-s');
|
|
435
|
+
});
|
|
436
|
+
it('throws SessionNotFoundError for unknown instanceId', async () => {
|
|
437
|
+
const conn = await BridgeConnection.connectAsync({
|
|
438
|
+
port: 0,
|
|
439
|
+
keepAlive: true,
|
|
440
|
+
});
|
|
441
|
+
connections.push(conn);
|
|
442
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-1', {
|
|
443
|
+
instanceId: 'inst-1',
|
|
444
|
+
});
|
|
445
|
+
openClients.push(ws);
|
|
446
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
447
|
+
await expect(conn.resolveSessionAsync(undefined, undefined, 'nonexistent-inst')).rejects.toThrow(SessionNotFoundError);
|
|
448
|
+
});
|
|
449
|
+
});
|
|
450
|
+
describe('waitForSession', () => {
|
|
451
|
+
it('resolves immediately when sessions already exist', async () => {
|
|
452
|
+
const conn = await BridgeConnection.connectAsync({
|
|
453
|
+
port: 0,
|
|
454
|
+
keepAlive: true,
|
|
455
|
+
});
|
|
456
|
+
connections.push(conn);
|
|
457
|
+
const { ws } = await performRegisterHandshake(conn.port, 'existing-session', {
|
|
458
|
+
instanceId: 'inst-1',
|
|
459
|
+
});
|
|
460
|
+
openClients.push(ws);
|
|
461
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
462
|
+
const session = await conn.waitForSessionAsync();
|
|
463
|
+
expect(session.info.sessionId).toBe('existing-session');
|
|
464
|
+
});
|
|
465
|
+
it('resolves when a plugin connects', async () => {
|
|
466
|
+
const conn = await BridgeConnection.connectAsync({
|
|
467
|
+
port: 0,
|
|
468
|
+
keepAlive: true,
|
|
469
|
+
});
|
|
470
|
+
connections.push(conn);
|
|
471
|
+
// Start waiting before plugin connects
|
|
472
|
+
const waitPromise = conn.waitForSessionAsync(5000);
|
|
473
|
+
// Connect plugin after a short delay
|
|
474
|
+
setTimeout(async () => {
|
|
475
|
+
const { ws } = await performRegisterHandshake(conn.port, 'late-session', {
|
|
476
|
+
instanceId: 'inst-1',
|
|
477
|
+
});
|
|
478
|
+
openClients.push(ws);
|
|
479
|
+
}, 100);
|
|
480
|
+
const session = await waitPromise;
|
|
481
|
+
expect(session.info.sessionId).toBe('late-session');
|
|
482
|
+
});
|
|
483
|
+
it('rejects after timeout with no plugin', async () => {
|
|
484
|
+
vi.useFakeTimers();
|
|
485
|
+
try {
|
|
486
|
+
const conn = await BridgeConnection.connectAsync({
|
|
487
|
+
port: 0,
|
|
488
|
+
keepAlive: true,
|
|
489
|
+
});
|
|
490
|
+
connections.push(conn);
|
|
491
|
+
const waitPromise = conn.waitForSessionAsync(500);
|
|
492
|
+
// Advance past the timeout
|
|
493
|
+
vi.advanceTimersByTime(600);
|
|
494
|
+
await expect(waitPromise).rejects.toThrow('Timed out waiting for a session');
|
|
495
|
+
}
|
|
496
|
+
finally {
|
|
497
|
+
vi.useRealTimers();
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
describe('waitForSessionsToSettleAsync', () => {
|
|
502
|
+
it('returns when no plugin appears within firstSessionTimeout', async () => {
|
|
503
|
+
const conn = await BridgeConnection.connectAsync({
|
|
504
|
+
port: 0,
|
|
505
|
+
keepAlive: true,
|
|
506
|
+
});
|
|
507
|
+
connections.push(conn);
|
|
508
|
+
const start = Date.now();
|
|
509
|
+
await conn.waitForSessionsToSettleAsync({
|
|
510
|
+
firstSessionTimeout: 150,
|
|
511
|
+
settleMs: 100,
|
|
512
|
+
maxMs: 1000,
|
|
513
|
+
});
|
|
514
|
+
const elapsed = Date.now() - start;
|
|
515
|
+
// Should resolve once firstSessionTimeout elapses with no plugin,
|
|
516
|
+
// not wait the full settleMs window.
|
|
517
|
+
expect(elapsed).toBeGreaterThanOrEqual(140);
|
|
518
|
+
expect(elapsed).toBeLessThan(400);
|
|
519
|
+
expect(conn.listSessions()).toHaveLength(0);
|
|
520
|
+
});
|
|
521
|
+
it('settles after settleMs of quiet time when one plugin connects', async () => {
|
|
522
|
+
const conn = await BridgeConnection.connectAsync({
|
|
523
|
+
port: 0,
|
|
524
|
+
keepAlive: true,
|
|
525
|
+
});
|
|
526
|
+
connections.push(conn);
|
|
527
|
+
let pluginConnectedAt = 0;
|
|
528
|
+
conn.once('session-connected', () => {
|
|
529
|
+
pluginConnectedAt = Date.now();
|
|
530
|
+
});
|
|
531
|
+
// Schedule a single plugin to connect mid-settle.
|
|
532
|
+
setTimeout(async () => {
|
|
533
|
+
const { ws } = await performRegisterHandshake(conn.port, 'lone-session');
|
|
534
|
+
openClients.push(ws);
|
|
535
|
+
}, 50);
|
|
536
|
+
await conn.waitForSessionsToSettleAsync({
|
|
537
|
+
firstSessionTimeout: 2000,
|
|
538
|
+
settleMs: 200,
|
|
539
|
+
maxMs: 5000,
|
|
540
|
+
});
|
|
541
|
+
const finishedAt = Date.now();
|
|
542
|
+
expect(pluginConnectedAt).toBeGreaterThan(0);
|
|
543
|
+
// settle should have waited at least settleMs after plugin connected.
|
|
544
|
+
expect(finishedAt - pluginConnectedAt).toBeGreaterThanOrEqual(180);
|
|
545
|
+
expect(conn.listSessions()).toHaveLength(1);
|
|
546
|
+
});
|
|
547
|
+
it('resets settle timer when a second plugin connects within window', async () => {
|
|
548
|
+
const conn = await BridgeConnection.connectAsync({
|
|
549
|
+
port: 0,
|
|
550
|
+
keepAlive: true,
|
|
551
|
+
});
|
|
552
|
+
connections.push(conn);
|
|
553
|
+
const connectTimes = [];
|
|
554
|
+
conn.on('session-connected', () => {
|
|
555
|
+
connectTimes.push(Date.now());
|
|
556
|
+
});
|
|
557
|
+
setTimeout(async () => {
|
|
558
|
+
const { ws } = await performRegisterHandshake(conn.port, 'first');
|
|
559
|
+
openClients.push(ws);
|
|
560
|
+
}, 50);
|
|
561
|
+
// Second plugin within settleMs (200) of the first → resets timer.
|
|
562
|
+
setTimeout(async () => {
|
|
563
|
+
const { ws } = await performRegisterHandshake(conn.port, 'second');
|
|
564
|
+
openClients.push(ws);
|
|
565
|
+
}, 180);
|
|
566
|
+
await conn.waitForSessionsToSettleAsync({
|
|
567
|
+
firstSessionTimeout: 2000,
|
|
568
|
+
settleMs: 200,
|
|
569
|
+
maxMs: 5000,
|
|
570
|
+
});
|
|
571
|
+
const finishedAt = Date.now();
|
|
572
|
+
expect(connectTimes).toHaveLength(2);
|
|
573
|
+
// Settle should have waited at least settleMs after the SECOND plugin.
|
|
574
|
+
const lastConnectAt = connectTimes[1];
|
|
575
|
+
expect(finishedAt - lastConnectAt).toBeGreaterThanOrEqual(180);
|
|
576
|
+
expect(conn.listSessions()).toHaveLength(2);
|
|
577
|
+
});
|
|
578
|
+
it('caps wait at maxMs when sessions stream continuously', async () => {
|
|
579
|
+
const conn = await BridgeConnection.connectAsync({
|
|
580
|
+
port: 0,
|
|
581
|
+
keepAlive: true,
|
|
582
|
+
});
|
|
583
|
+
connections.push(conn);
|
|
584
|
+
let firstConnectedAt = 0;
|
|
585
|
+
conn.once('session-connected', () => {
|
|
586
|
+
firstConnectedAt = Date.now();
|
|
587
|
+
});
|
|
588
|
+
// Stream plugins every 80ms (well within settleMs=200) so the settle
|
|
589
|
+
// timer would never fire on its own — only maxMs can stop it.
|
|
590
|
+
const streamTimers = [];
|
|
591
|
+
for (let i = 0; i < 8; i++) {
|
|
592
|
+
const t = setTimeout(async () => {
|
|
593
|
+
try {
|
|
594
|
+
const { ws } = await performRegisterHandshake(conn.port, `stream-${i}`);
|
|
595
|
+
openClients.push(ws);
|
|
596
|
+
}
|
|
597
|
+
catch {
|
|
598
|
+
// Connection may close while streaming — fine.
|
|
599
|
+
}
|
|
600
|
+
}, 50 + i * 80);
|
|
601
|
+
streamTimers.push(t);
|
|
602
|
+
}
|
|
603
|
+
try {
|
|
604
|
+
await conn.waitForSessionsToSettleAsync({
|
|
605
|
+
firstSessionTimeout: 2000,
|
|
606
|
+
settleMs: 200,
|
|
607
|
+
maxMs: 300,
|
|
608
|
+
});
|
|
609
|
+
const finishedAt = Date.now();
|
|
610
|
+
expect(firstConnectedAt).toBeGreaterThan(0);
|
|
611
|
+
// Should hit maxMs cap (~300ms) rather than wait for settleMs quiet.
|
|
612
|
+
expect(finishedAt - firstConnectedAt).toBeLessThan(450);
|
|
613
|
+
expect(finishedAt - firstConnectedAt).toBeGreaterThanOrEqual(280);
|
|
614
|
+
}
|
|
615
|
+
finally {
|
|
616
|
+
for (const t of streamTimers)
|
|
617
|
+
clearTimeout(t);
|
|
618
|
+
}
|
|
619
|
+
});
|
|
620
|
+
it('returns immediately when role is client', async () => {
|
|
621
|
+
const host = await BridgeConnection.connectAsync({
|
|
622
|
+
port: 0,
|
|
623
|
+
keepAlive: true,
|
|
624
|
+
});
|
|
625
|
+
connections.push(host);
|
|
626
|
+
const client = await BridgeConnection.connectAsync({
|
|
627
|
+
port: host.port,
|
|
628
|
+
keepAlive: true,
|
|
629
|
+
local: true,
|
|
630
|
+
});
|
|
631
|
+
connections.push(client);
|
|
632
|
+
expect(client.role).toBe('client');
|
|
633
|
+
const start = Date.now();
|
|
634
|
+
await client.waitForSessionsToSettleAsync({
|
|
635
|
+
firstSessionTimeout: 5000,
|
|
636
|
+
settleMs: 1000,
|
|
637
|
+
maxMs: 10_000,
|
|
638
|
+
});
|
|
639
|
+
const elapsed = Date.now() - start;
|
|
640
|
+
// Should bail at the role check, not wait on any timer.
|
|
641
|
+
expect(elapsed).toBeLessThan(50);
|
|
642
|
+
});
|
|
643
|
+
});
|
|
644
|
+
describe('events', () => {
|
|
645
|
+
it('emits session-connected when plugin registers', async () => {
|
|
646
|
+
const conn = await BridgeConnection.connectAsync({
|
|
647
|
+
port: 0,
|
|
648
|
+
keepAlive: true,
|
|
649
|
+
});
|
|
650
|
+
connections.push(conn);
|
|
651
|
+
const connectedPromise = new Promise((resolve) => {
|
|
652
|
+
conn.on('session-connected', resolve);
|
|
653
|
+
});
|
|
654
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-evt', {
|
|
655
|
+
instanceId: 'inst-1',
|
|
656
|
+
});
|
|
657
|
+
openClients.push(ws);
|
|
658
|
+
const session = await connectedPromise;
|
|
659
|
+
expect(session.info.sessionId).toBe('session-evt');
|
|
660
|
+
});
|
|
661
|
+
it('emits session-disconnected when plugin closes', async () => {
|
|
662
|
+
const conn = await BridgeConnection.connectAsync({
|
|
663
|
+
port: 0,
|
|
664
|
+
keepAlive: true,
|
|
665
|
+
});
|
|
666
|
+
connections.push(conn);
|
|
667
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-dc', {
|
|
668
|
+
instanceId: 'inst-1',
|
|
669
|
+
});
|
|
670
|
+
openClients.push(ws);
|
|
671
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
672
|
+
const disconnectedPromise = new Promise((resolve) => {
|
|
673
|
+
conn.on('session-disconnected', resolve);
|
|
674
|
+
});
|
|
675
|
+
ws.close();
|
|
676
|
+
const sessionId = await disconnectedPromise;
|
|
677
|
+
expect(sessionId).toBe('session-dc');
|
|
678
|
+
});
|
|
679
|
+
it('emits instance-connected for first session of an instance', async () => {
|
|
680
|
+
const conn = await BridgeConnection.connectAsync({
|
|
681
|
+
port: 0,
|
|
682
|
+
keepAlive: true,
|
|
683
|
+
});
|
|
684
|
+
connections.push(conn);
|
|
685
|
+
const instancePromise = new Promise((resolve) => {
|
|
686
|
+
conn.on('instance-connected', (instance) => {
|
|
687
|
+
resolve(instance);
|
|
688
|
+
});
|
|
689
|
+
});
|
|
690
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-1', {
|
|
691
|
+
instanceId: 'inst-new',
|
|
692
|
+
placeName: 'NewPlace',
|
|
693
|
+
});
|
|
694
|
+
openClients.push(ws);
|
|
695
|
+
const instance = await instancePromise;
|
|
696
|
+
expect(instance.instanceId).toBe('inst-new');
|
|
697
|
+
});
|
|
698
|
+
it('emits instance-disconnected when last session of an instance disconnects', async () => {
|
|
699
|
+
const conn = await BridgeConnection.connectAsync({
|
|
700
|
+
port: 0,
|
|
701
|
+
keepAlive: true,
|
|
702
|
+
});
|
|
703
|
+
connections.push(conn);
|
|
704
|
+
const { ws } = await performRegisterHandshake(conn.port, 'session-last', {
|
|
705
|
+
instanceId: 'inst-only',
|
|
706
|
+
});
|
|
707
|
+
openClients.push(ws);
|
|
708
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
709
|
+
const instanceDisconnectedPromise = new Promise((resolve) => {
|
|
710
|
+
conn.on('instance-disconnected', resolve);
|
|
711
|
+
});
|
|
712
|
+
ws.close();
|
|
713
|
+
const instanceId = await instanceDisconnectedPromise;
|
|
714
|
+
expect(instanceId).toBe('inst-only');
|
|
715
|
+
});
|
|
716
|
+
it('does not emit instance-disconnected when other contexts remain', async () => {
|
|
717
|
+
const conn = await BridgeConnection.connectAsync({
|
|
718
|
+
port: 0,
|
|
719
|
+
keepAlive: true,
|
|
720
|
+
});
|
|
721
|
+
connections.push(conn);
|
|
722
|
+
// Connect edit and server contexts for the same instance
|
|
723
|
+
const { ws: wsEdit } = await performRegisterHandshake(conn.port, 'edit-ctx', {
|
|
724
|
+
instanceId: 'inst-play',
|
|
725
|
+
state: 'Edit',
|
|
726
|
+
});
|
|
727
|
+
openClients.push(wsEdit);
|
|
728
|
+
const { ws: wsServer } = await performRegisterHandshake(conn.port, 'server-ctx', {
|
|
729
|
+
instanceId: 'inst-play',
|
|
730
|
+
state: 'Server',
|
|
731
|
+
});
|
|
732
|
+
openClients.push(wsServer);
|
|
733
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
734
|
+
let instanceDisconnectedFired = false;
|
|
735
|
+
conn.on('instance-disconnected', () => {
|
|
736
|
+
instanceDisconnectedFired = true;
|
|
737
|
+
});
|
|
738
|
+
// Disconnect only the server context
|
|
739
|
+
const sessionDisconnectedPromise = new Promise((resolve) => {
|
|
740
|
+
conn.on('session-disconnected', resolve);
|
|
741
|
+
});
|
|
742
|
+
wsServer.close();
|
|
743
|
+
await sessionDisconnectedPromise;
|
|
744
|
+
// Wait a bit more to ensure no stray event
|
|
745
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
746
|
+
// instance-disconnected should NOT have fired (edit context still connected)
|
|
747
|
+
expect(instanceDisconnectedFired).toBe(false);
|
|
748
|
+
expect(conn.listInstances()).toHaveLength(1);
|
|
749
|
+
});
|
|
750
|
+
it('fires multiple session-connected events for multiple plugins', async () => {
|
|
751
|
+
const conn = await BridgeConnection.connectAsync({
|
|
752
|
+
port: 0,
|
|
753
|
+
keepAlive: true,
|
|
754
|
+
});
|
|
755
|
+
connections.push(conn);
|
|
756
|
+
const connectedIds = [];
|
|
757
|
+
conn.on('session-connected', (session) => {
|
|
758
|
+
connectedIds.push(session.info.sessionId);
|
|
759
|
+
});
|
|
760
|
+
const { ws: ws1 } = await performRegisterHandshake(conn.port, 'session-1', {
|
|
761
|
+
instanceId: 'inst-1',
|
|
762
|
+
});
|
|
763
|
+
openClients.push(ws1);
|
|
764
|
+
const { ws: ws2 } = await performRegisterHandshake(conn.port, 'session-2', {
|
|
765
|
+
instanceId: 'inst-2',
|
|
766
|
+
});
|
|
767
|
+
openClients.push(ws2);
|
|
768
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
769
|
+
expect(connectedIds.sort()).toEqual(['session-1', 'session-2']);
|
|
770
|
+
});
|
|
771
|
+
});
|
|
772
|
+
});
|
|
773
|
+
//# sourceMappingURL=bridge-connection.test.js.map
|