runtimepy 5.5.0__tar.gz → 5.6.1__tar.gz
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.
- {runtimepy-5.5.0/runtimepy.egg-info → runtimepy-5.6.1}/PKG-INFO +14 -7
- {runtimepy-5.5.0 → runtimepy-5.6.1}/README.md +11 -4
- {runtimepy-5.5.0 → runtimepy-5.6.1}/pyproject.toml +1 -1
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/__init__.py +2 -2
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/commands/server.py +35 -3
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/App.js +33 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/PlotModalManager.js +3 -1
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/WindowHashManager.js +17 -2
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/init.js +12 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/util.js +12 -3
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/worker.js +18 -3
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/tcp/__init__.py +1 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/__init__.py +21 -20
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/env/__init__.py +2 -2
- runtimepy-5.6.1/runtimepy/net/server/app/env/settings.py +59 -0
- runtimepy-5.6.1/runtimepy/net/ssl.py +33 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/tcp/connection.py +37 -10
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/tcp/create.py +2 -1
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/tcp/http/__init__.py +6 -1
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/util.py +11 -2
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/websocket/connection.py +28 -6
- {runtimepy-5.5.0 → runtimepy-5.6.1/runtimepy.egg-info}/PKG-INFO +14 -7
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy.egg-info/SOURCES.txt +2 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/LICENSE +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/__main__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/app.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/array.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/command/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/command/parser.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/command/processor.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/command/result.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/create.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/file.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/sample.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/environment/telemetry.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/event/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/event/header.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/channel/registry.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/codec/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/codec/protocol/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/codec/protocol/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/codec/protocol/json.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/codec/system/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/commands/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/commands/all.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/commands/arbiter.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/commands/common.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/commands/mtu.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/commands/task.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/commands/tftp.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/commands/tui.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/control/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/control/env/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/control/source.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/control/step.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/browser.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/css/bootstrap_extra.css +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/css/main.css +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/dummy_load.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/factories.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/favicon.ico +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/DataConnection.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/JsonConnection.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/audio.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/ChannelTable.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/DataConnection.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/JsonConnection.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/OverlayManager.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/Plot.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/PlotDrawer.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/PlotManager.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/PointBuffer.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/PointManager.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/TabFilter.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/TabInterface.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/UnitSystem.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/classes/WorkerInterface.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/events.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/main.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/tab/env.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/tab/sound.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/third-party/webgl-debug.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/js/unused/pyodide.js +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/sample_telemetry.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/BitFields.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/Channel.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/ChannelCommand.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/ChannelRegistry.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/ClientConnectionConfig.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/ConnectionArbiterConfig.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/EnumRegistry.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/FindFile.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/PeerProcessConfig.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/RuntimeEnum.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/ServerConnectionConfig.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/StructConfig.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/TaskConfig.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/channel_controls.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/has_config.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/has_factory.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/has_name.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/schemas/has_request_flag.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/server.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/server_base.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/server_dev.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/data/tftp_server.yaml +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/dev_requirements.txt +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/entry.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/enum/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/enum/registry.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/enum/types.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/mapping.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/message/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/message/handlers.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/message/interface.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/message/types.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/metrics/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/metrics/channel.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/metrics/connection.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/metrics/task.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/mixins/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/mixins/async_command.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/mixins/enum.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/mixins/environment.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/mixins/finalize.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/mixins/logging.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/mixins/psutil.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/mixins/regex.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/mixins/trig.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/apps/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/config/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/config/codec.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/config/util.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/factory/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/factory/connection.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/factory/task.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/housekeeping/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/imports/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/imports/util.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/info.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/result.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/struct/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/task.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/tcp/json.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/udp.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/arbiter/websocket.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/backoff.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/connection.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/factories/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/http/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/http/common.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/http/header.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/http/request_target.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/http/response.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/http/state.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/http/version.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/manager.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/mixin.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/mtu.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/bootstrap/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/bootstrap/elements.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/bootstrap/tabs.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/create.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/elements.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/env/modal.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/env/tab/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/env/tab/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/env/tab/controls.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/env/tab/html.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/env/tab/message.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/env/widgets.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/files.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/landing_page.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/placeholder.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/pyodide.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/sound.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/app/tab.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/html.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/json.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/struct/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/websocket/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/server/websocket/state.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/stream/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/stream/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/stream/json/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/stream/string.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/tcp/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/tcp/protocol.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/tcp/scpi/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/tcp/telnet/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/tcp/telnet/codes.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/tcp/telnet/np_05b.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/udp/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/udp/connection.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/udp/create.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/udp/protocol.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/udp/queue.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/udp/tftp/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/udp/tftp/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/udp/tftp/endpoint.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/udp/tftp/enums.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/udp/tftp/io.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/net/websocket/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/noise/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/array/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/bool.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/byte_order.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/evaluation.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/field/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/field/fields.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/field/manager/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/field/manager/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/float.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/int.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/scaling.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/serializable/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/serializable/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/serializable/fixed.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/serializable/framer.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/serializable/prefixed.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/string.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/types/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/types/base.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/types/bool.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/types/bounds.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/types/float.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/primitives/types/int.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/py.typed +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/registry/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/registry/bool.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/registry/item.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/registry/name.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/requirements.txt +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/sample/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/sample/peer.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/sample/program.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/schemas.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/struct/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/subprocess/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/subprocess/interface.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/subprocess/peer.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/subprocess/program.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/subprocess/protocol.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/task/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/task/asynchronous.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/task/basic/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/task/basic/manager.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/task/basic/periodic.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/task/sample.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/task/trig/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/telemetry/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/telemetry/sample.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/tui/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/tui/channels/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/tui/cursor.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/tui/mixin.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/tui/mock.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/tui/task.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/ui/__init__.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/ui/controls.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy/util.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy.egg-info/dependency_links.txt +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy.egg-info/entry_points.txt +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy.egg-info/requires.txt +2 -2
- {runtimepy-5.5.0 → runtimepy-5.6.1}/runtimepy.egg-info/top_level.txt +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/setup.cfg +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/setup.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/tests/test_entry.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/tests/test_mapping.py +0 -0
- {runtimepy-5.5.0 → runtimepy-5.6.1}/tests/test_resources.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: runtimepy
|
|
3
|
-
Version: 5.
|
|
3
|
+
Version: 5.6.1
|
|
4
4
|
Summary: A framework for implementing Python services.
|
|
5
5
|
Home-page: https://github.com/vkottler/runtimepy
|
|
6
6
|
Author: Vaughn Kottler
|
|
@@ -17,10 +17,10 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
17
17
|
Requires-Python: >=3.11
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
License-File: LICENSE
|
|
20
|
-
Requires-Dist:
|
|
20
|
+
Requires-Dist: vcorelib>=3.3.1
|
|
21
21
|
Requires-Dist: svgen>=0.6.8
|
|
22
|
+
Requires-Dist: websockets
|
|
22
23
|
Requires-Dist: psutil
|
|
23
|
-
Requires-Dist: vcorelib>=3.3.1
|
|
24
24
|
Provides-Extra: test
|
|
25
25
|
Requires-Dist: pylint; extra == "test"
|
|
26
26
|
Requires-Dist: flake8; extra == "test"
|
|
@@ -44,11 +44,11 @@ Requires-Dist: uvloop; (sys_platform != "win32" and sys_platform != "cygwin") an
|
|
|
44
44
|
=====================================
|
|
45
45
|
generator=datazen
|
|
46
46
|
version=3.1.4
|
|
47
|
-
hash=
|
|
47
|
+
hash=a82bbd8413b0036b345251da16b462c3
|
|
48
48
|
=====================================
|
|
49
49
|
-->
|
|
50
50
|
|
|
51
|
-
# runtimepy ([5.
|
|
51
|
+
# runtimepy ([5.6.1](https://pypi.org/project/runtimepy/))
|
|
52
52
|
|
|
53
53
|
[](https://pypi.org/project/runtimepy/)
|
|
54
54
|

|
|
@@ -165,8 +165,10 @@ options:
|
|
|
165
165
|
```
|
|
166
166
|
$ ./venv3.12/bin/runtimepy server -h
|
|
167
167
|
|
|
168
|
-
usage: runtimepy server [-h] [-i] [-w] [--no-poller] [--
|
|
169
|
-
[
|
|
168
|
+
usage: runtimepy server [-h] [-i] [-w] [--no-poller] [--cafile CAFILE]
|
|
169
|
+
[--capath CAPATH] [--cadata CADATA]
|
|
170
|
+
[--certfile CERTFILE] [--keyfile KEYFILE]
|
|
171
|
+
[--host HOST] [-p PORT] [-u] [-l]
|
|
170
172
|
factory [configs ...]
|
|
171
173
|
|
|
172
174
|
positional arguments:
|
|
@@ -181,6 +183,11 @@ options:
|
|
|
181
183
|
ensure that a 'wait_for_stop' application method is
|
|
182
184
|
run last
|
|
183
185
|
--no-poller don't run a connection-metrics poller task
|
|
186
|
+
--cafile CAFILE passed directly to instantiation
|
|
187
|
+
--capath CAPATH passed directly to instantiation
|
|
188
|
+
--cadata CADATA passed directly to instantiation
|
|
189
|
+
--certfile CERTFILE passed directly to instantiation
|
|
190
|
+
--keyfile KEYFILE passed directly to instantiation
|
|
184
191
|
--host HOST host address to listen on (default: '0.0.0.0')
|
|
185
192
|
-p PORT, --port PORT port to listen on (default: 0)
|
|
186
193
|
-u, --udp whether or not this is a UDP-based server (otherwise
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
=====================================
|
|
3
3
|
generator=datazen
|
|
4
4
|
version=3.1.4
|
|
5
|
-
hash=
|
|
5
|
+
hash=a82bbd8413b0036b345251da16b462c3
|
|
6
6
|
=====================================
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
|
-
# runtimepy ([5.
|
|
9
|
+
# runtimepy ([5.6.1](https://pypi.org/project/runtimepy/))
|
|
10
10
|
|
|
11
11
|
[](https://pypi.org/project/runtimepy/)
|
|
12
12
|

|
|
@@ -123,8 +123,10 @@ options:
|
|
|
123
123
|
```
|
|
124
124
|
$ ./venv3.12/bin/runtimepy server -h
|
|
125
125
|
|
|
126
|
-
usage: runtimepy server [-h] [-i] [-w] [--no-poller] [--
|
|
127
|
-
[
|
|
126
|
+
usage: runtimepy server [-h] [-i] [-w] [--no-poller] [--cafile CAFILE]
|
|
127
|
+
[--capath CAPATH] [--cadata CADATA]
|
|
128
|
+
[--certfile CERTFILE] [--keyfile KEYFILE]
|
|
129
|
+
[--host HOST] [-p PORT] [-u] [-l]
|
|
128
130
|
factory [configs ...]
|
|
129
131
|
|
|
130
132
|
positional arguments:
|
|
@@ -139,6 +141,11 @@ options:
|
|
|
139
141
|
ensure that a 'wait_for_stop' application method is
|
|
140
142
|
run last
|
|
141
143
|
--no-poller don't run a connection-metrics poller task
|
|
144
|
+
--cafile CAFILE passed directly to instantiation
|
|
145
|
+
--capath CAPATH passed directly to instantiation
|
|
146
|
+
--cadata CADATA passed directly to instantiation
|
|
147
|
+
--certfile CERTFILE passed directly to instantiation
|
|
148
|
+
--keyfile KEYFILE passed directly to instantiation
|
|
142
149
|
--host HOST host address to listen on (default: '0.0.0.0')
|
|
143
150
|
-p PORT, --port PORT port to listen on (default: 0)
|
|
144
151
|
-u, --udp whether or not this is a UDP-based server (otherwise
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# =====================================
|
|
2
2
|
# generator=datazen
|
|
3
3
|
# version=3.1.4
|
|
4
|
-
# hash=
|
|
4
|
+
# hash=d200504a923864c56b7eb211fd10233a
|
|
5
5
|
# =====================================
|
|
6
6
|
|
|
7
7
|
"""
|
|
@@ -10,7 +10,7 @@ Useful defaults and other package metadata.
|
|
|
10
10
|
|
|
11
11
|
DESCRIPTION = "A framework for implementing Python services."
|
|
12
12
|
PKG_NAME = "runtimepy"
|
|
13
|
-
VERSION = "5.
|
|
13
|
+
VERSION = "5.6.1"
|
|
14
14
|
|
|
15
15
|
# runtimepy-specific content.
|
|
16
16
|
METRICS_NAME = "metrics"
|
|
@@ -14,6 +14,9 @@ from vcorelib.args import CommandFunction as _CommandFunction
|
|
|
14
14
|
from runtimepy.commands.arbiter import arbiter_cmd
|
|
15
15
|
from runtimepy.commands.common import FACTORIES, arbiter_args, cmd_with_jit
|
|
16
16
|
|
|
17
|
+
SSL_PASSTHROUGH = ["cafile", "capath", "cadata", "certfile"]
|
|
18
|
+
PASSTHROUGH = SSL_PASSTHROUGH + ["keyfile"]
|
|
19
|
+
|
|
17
20
|
|
|
18
21
|
def port_name(args: _Namespace, port: str = "port") -> str:
|
|
19
22
|
"""Get the name for a connection factory's port."""
|
|
@@ -25,7 +28,7 @@ def server_data(args: _Namespace) -> dict[str, Any]:
|
|
|
25
28
|
|
|
26
29
|
return {
|
|
27
30
|
"factory": args.factory,
|
|
28
|
-
"kwargs":
|
|
31
|
+
"kwargs": get_kwargs(args, port=f"${port_name(args)}", host=args.host),
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
|
|
@@ -34,6 +37,26 @@ def is_websocket(args: _Namespace) -> bool:
|
|
|
34
37
|
return "websocket" in args.factory.lower()
|
|
35
38
|
|
|
36
39
|
|
|
40
|
+
def is_ssl(kwargs: dict[str, Any]) -> bool:
|
|
41
|
+
"""Determine if server arugments indicate SSL use."""
|
|
42
|
+
return any(x in kwargs for x in SSL_PASSTHROUGH)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_kwargs(args: _Namespace, **kwargs) -> dict[str, Any]:
|
|
46
|
+
"""Get boilerplate kwargs."""
|
|
47
|
+
|
|
48
|
+
new_kwargs: dict[str, Any] = {**kwargs}
|
|
49
|
+
|
|
50
|
+
# Pass additional arguments through.
|
|
51
|
+
print(args)
|
|
52
|
+
for opt in PASSTHROUGH:
|
|
53
|
+
value = getattr(args, opt, None)
|
|
54
|
+
if value is not None:
|
|
55
|
+
new_kwargs[opt] = value
|
|
56
|
+
|
|
57
|
+
return new_kwargs
|
|
58
|
+
|
|
59
|
+
|
|
37
60
|
def client_data(args: _Namespace) -> dict[str, Any]:
|
|
38
61
|
"""Get client data based on command-line arguments."""
|
|
39
62
|
|
|
@@ -43,7 +66,9 @@ def client_data(args: _Namespace) -> dict[str, Any]:
|
|
|
43
66
|
kwargs: dict[str, Any] = {}
|
|
44
67
|
|
|
45
68
|
if is_websocket(args):
|
|
46
|
-
arg_list.append(
|
|
69
|
+
arg_list.append(
|
|
70
|
+
f"ws{'s' if is_ssl(get_kwargs(args)) else ''}://localhost:{port}"
|
|
71
|
+
)
|
|
47
72
|
elif not args.udp:
|
|
48
73
|
kwargs["host"] = "localhost"
|
|
49
74
|
kwargs["port"] = port
|
|
@@ -76,7 +101,9 @@ def config_data(args: _Namespace) -> dict[str, Any]:
|
|
|
76
101
|
{
|
|
77
102
|
"name": port_name(args, port="server"),
|
|
78
103
|
"factory": args.factory,
|
|
79
|
-
"kwargs":
|
|
104
|
+
"kwargs": get_kwargs(
|
|
105
|
+
args, local_addr=["0.0.0.0", f"${port_name(args)}"]
|
|
106
|
+
),
|
|
80
107
|
}
|
|
81
108
|
)
|
|
82
109
|
|
|
@@ -108,6 +135,11 @@ def add_server_cmd(parser: _ArgumentParser) -> _CommandFunction:
|
|
|
108
135
|
"""Add server-command arguments to its parser."""
|
|
109
136
|
|
|
110
137
|
with arbiter_args(parser, nargs="*"):
|
|
138
|
+
for optional in PASSTHROUGH:
|
|
139
|
+
parser.add_argument(
|
|
140
|
+
f"--{optional}", help="passed directly to instantiation"
|
|
141
|
+
)
|
|
142
|
+
|
|
111
143
|
parser.add_argument(
|
|
112
144
|
"--host",
|
|
113
145
|
default="0.0.0.0",
|
|
@@ -53,6 +53,12 @@ class App {
|
|
|
53
53
|
this.switchTab(hash.tab);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/* Handle settings controls. */
|
|
57
|
+
loadSettings();
|
|
58
|
+
|
|
59
|
+
/* Handle individual settings. */
|
|
60
|
+
this.handleInitialMinTxPeriod();
|
|
61
|
+
|
|
56
62
|
startMainLoop();
|
|
57
63
|
}
|
|
58
64
|
}, {once : true});
|
|
@@ -62,6 +68,33 @@ class App {
|
|
|
62
68
|
|
|
63
69
|
bootstrap_init();
|
|
64
70
|
}
|
|
71
|
+
|
|
72
|
+
handleInitialMinTxPeriod() {
|
|
73
|
+
if ("min-tx-period-ms" in settings) {
|
|
74
|
+
/* Set up event handle. */
|
|
75
|
+
setupCursorContext(settings["min-tx-period-ms"], (elem, down, move,
|
|
76
|
+
up) => {
|
|
77
|
+
setupCursorMove(
|
|
78
|
+
elem, down, move, up,
|
|
79
|
+
(event) => { this.updateMinTxPeriod(Number(event.target.value)); });
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/* Set slider to correct value. */
|
|
83
|
+
settings["min-tx-period-ms"].value = hash.minTxPeriod;
|
|
84
|
+
settings["min-tx-period-ms"].title = hash.minTxPeriod;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
this.updateMinTxPeriod();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
updateMinTxPeriod(value) {
|
|
91
|
+
if (value || value === 0) {
|
|
92
|
+
hash.setMinTxPeriod(value);
|
|
93
|
+
settings["min-tx-period-ms"].title = value;
|
|
94
|
+
}
|
|
95
|
+
this.worker.postMessage(
|
|
96
|
+
{"event" : {"worker" : {"min-tx-period-ms" : hash.minTxPeriod}}});
|
|
97
|
+
}
|
|
65
98
|
}
|
|
66
99
|
|
|
67
100
|
function startMainLoop() {
|
|
@@ -6,6 +6,8 @@ class PlotModalManager {
|
|
|
6
6
|
this.body = this.container.querySelector(".modal-body");
|
|
7
7
|
this.footer = this.container.querySelector(".modal-footer");
|
|
8
8
|
|
|
9
|
+
this.plotStatus = this.container.querySelector("#plot-status-inner");
|
|
10
|
+
|
|
9
11
|
this.byEnv = {};
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -34,7 +36,7 @@ class PlotModalManager {
|
|
|
34
36
|
}
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
this.
|
|
39
|
+
this.plotStatus.innerHTML = content;
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -9,6 +9,7 @@ class WindowHashManager {
|
|
|
9
9
|
this.channelsShown = true;
|
|
10
10
|
this.plotChannels = {};
|
|
11
11
|
this.filters = {};
|
|
12
|
+
this.minTxPeriod = 0.0;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
tabClick(event) {
|
|
@@ -160,8 +161,13 @@ class WindowHashManager {
|
|
|
160
161
|
for (let item of split) {
|
|
161
162
|
if (item.includes("=")) {
|
|
162
163
|
let keyVal = item.split("=");
|
|
163
|
-
if (keyVal.length == 2
|
|
164
|
-
|
|
164
|
+
if (keyVal.length == 2) {
|
|
165
|
+
if (keyVal[0] == "filter" && keyVal[1]) {
|
|
166
|
+
this.updateTabFilter(keyVal[1]);
|
|
167
|
+
}
|
|
168
|
+
if (keyVal[0] == "min-tx-period-ms") {
|
|
169
|
+
this.minTxPeriod = Number(keyVal[1]);
|
|
170
|
+
}
|
|
165
171
|
}
|
|
166
172
|
}
|
|
167
173
|
}
|
|
@@ -176,6 +182,11 @@ class WindowHashManager {
|
|
|
176
182
|
return result;
|
|
177
183
|
}
|
|
178
184
|
|
|
185
|
+
setMinTxPeriod(value) {
|
|
186
|
+
this.minTxPeriod = value;
|
|
187
|
+
this.update();
|
|
188
|
+
}
|
|
189
|
+
|
|
179
190
|
buildHash() {
|
|
180
191
|
let hash = this.tab;
|
|
181
192
|
|
|
@@ -189,6 +200,10 @@ class WindowHashManager {
|
|
|
189
200
|
hash += ",hide-channels"
|
|
190
201
|
}
|
|
191
202
|
|
|
203
|
+
if (this.minTxPeriod != 0.0) {
|
|
204
|
+
hash += `,min-tx-period-ms=${this.minTxPeriod}`;
|
|
205
|
+
}
|
|
206
|
+
|
|
192
207
|
for (let tab in tabs) {
|
|
193
208
|
let firstChan = true;
|
|
194
209
|
|
|
@@ -46,3 +46,15 @@ function setupCursorMove(elem, down, move, up, handleMove) {
|
|
|
46
46
|
function randomHexColor() {
|
|
47
47
|
return "#" + (Math.random() * 0xFFFFFF << 0).toString(16).padStart(6, "0");
|
|
48
48
|
}
|
|
49
|
+
|
|
50
|
+
/* Load settings control mappings. */
|
|
51
|
+
let settings = {};
|
|
52
|
+
|
|
53
|
+
function loadSettings() {
|
|
54
|
+
for (const key of ["min-tx-period-ms"]) {
|
|
55
|
+
let elem = document.getElementById(`setting-${key}`);
|
|
56
|
+
if (elem) {
|
|
57
|
+
settings[key] = elem;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
function worker_config(config) {
|
|
2
2
|
let worker_cfg = {};
|
|
3
3
|
|
|
4
|
+
let port_name = "runtimepy_websocket";
|
|
5
|
+
let uri_prefix = "ws";
|
|
6
|
+
|
|
7
|
+
/* Ensured TLS is handled properly. */
|
|
8
|
+
if (location.protocol.includes("https")) {
|
|
9
|
+
port_name = "runtimepy_secure_websocket";
|
|
10
|
+
uri_prefix += "s";
|
|
11
|
+
}
|
|
12
|
+
|
|
4
13
|
/* Look for connections to establish. */
|
|
5
14
|
let ports = config["config"]["ports"];
|
|
6
15
|
for (let port_idx in ports) {
|
|
@@ -10,11 +19,11 @@ function worker_config(config) {
|
|
|
10
19
|
let hostname = window.location.hostname;
|
|
11
20
|
|
|
12
21
|
/* This business logic could use some work. */
|
|
13
|
-
if (port["name"].includes(
|
|
22
|
+
if (port["name"].includes(port_name)) {
|
|
14
23
|
if (port["name"].includes("data")) {
|
|
15
|
-
worker_cfg["data"] =
|
|
24
|
+
worker_cfg["data"] = `${uri_prefix}://${hostname}:` + port["port"];
|
|
16
25
|
} else {
|
|
17
|
-
worker_cfg["json"] =
|
|
26
|
+
worker_cfg["json"] = `${uri_prefix}://${hostname}:` + port["port"];
|
|
18
27
|
}
|
|
19
28
|
}
|
|
20
29
|
}
|
|
@@ -13,11 +13,16 @@ function create_connections(config) {
|
|
|
13
13
|
|
|
14
14
|
const plots = new PlotManager();
|
|
15
15
|
|
|
16
|
+
/* Used to control messaging rate with server. */
|
|
17
|
+
let minTxPeriod = 0.0;
|
|
18
|
+
|
|
16
19
|
async function message(data) {
|
|
17
20
|
if ("plot" in data) {
|
|
18
21
|
/* Forward the 'name' field. */
|
|
19
22
|
data["plot"]["name"] = data["name"];
|
|
20
23
|
await plots.handleMessage(data["plot"]);
|
|
24
|
+
} else if ("min-tx-period-ms" in data) {
|
|
25
|
+
minTxPeriod = data["min-tx-period-ms"];
|
|
21
26
|
} else {
|
|
22
27
|
console.log(`Message for worker:`);
|
|
23
28
|
console.log(data);
|
|
@@ -38,9 +43,14 @@ async function start(config) {
|
|
|
38
43
|
onmessage = async (event) => {
|
|
39
44
|
/* Handle messages meant for this thread. */
|
|
40
45
|
if ("event" in event.data && "worker" in event.data["event"]) {
|
|
46
|
+
let data = event.data["event"]["worker"];
|
|
47
|
+
|
|
41
48
|
/* Forward the 'name' field. */
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
if ("name" in event.data) {
|
|
50
|
+
data["name"] = event.data["name"];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
await message(data);
|
|
44
54
|
}
|
|
45
55
|
/* Forward all other messages to the server. */
|
|
46
56
|
else {
|
|
@@ -63,13 +73,18 @@ async function start(config) {
|
|
|
63
73
|
/* Tell main thread we're ready to go. */
|
|
64
74
|
postMessage(0);
|
|
65
75
|
|
|
76
|
+
let messageTxTime = 0.0;
|
|
77
|
+
|
|
66
78
|
/* Set up the main request-animation-frame loop. */
|
|
67
79
|
function render(time) {
|
|
68
80
|
/* Render plot. */
|
|
69
81
|
plots.render(time);
|
|
70
82
|
|
|
71
83
|
/* Keep the server synchronized with frames. */
|
|
72
|
-
|
|
84
|
+
if (messageTxTime + minTxPeriod <= time) {
|
|
85
|
+
conns["json"].send_json({"ui" : {"time" : time}});
|
|
86
|
+
messageTxTime = time;
|
|
87
|
+
}
|
|
73
88
|
|
|
74
89
|
requestAnimationFrame(render);
|
|
75
90
|
}
|
|
@@ -27,26 +27,27 @@ async def launch_browser(app: AppInfo) -> None:
|
|
|
27
27
|
"""
|
|
28
28
|
|
|
29
29
|
# Launch browser based on config option.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
30
|
+
for prefix in ["http", "https"]:
|
|
31
|
+
if config_param(app, f"xdg_open_{prefix}", False):
|
|
32
|
+
|
|
33
|
+
port: Any
|
|
34
|
+
for port in app.config["root"]["ports"]: # type: ignore
|
|
35
|
+
if f"{prefix}_server" in port["name"]:
|
|
36
|
+
# URI parameters.
|
|
37
|
+
hostname = config_param(app, "xdg_host", "localhost")
|
|
38
|
+
|
|
39
|
+
# Assemble URI.
|
|
40
|
+
uri = f"{prefix}://{hostname}:{port['port']}/"
|
|
41
|
+
|
|
42
|
+
# Add a fragment if one was specified.
|
|
43
|
+
fragment = config_param(app, "xdg_fragment", "")
|
|
44
|
+
if fragment:
|
|
45
|
+
uri += "#" + fragment
|
|
46
|
+
|
|
47
|
+
with suppress(FileNotFoundError):
|
|
48
|
+
await app.stack.enter_async_context(
|
|
49
|
+
spawn_exec("xdg-open", uri)
|
|
50
|
+
)
|
|
50
51
|
|
|
51
52
|
|
|
52
53
|
# Could add an interface for adding multiple applications.
|
|
@@ -11,6 +11,7 @@ from runtimepy.net.arbiter.info import AppInfo
|
|
|
11
11
|
from runtimepy.net.server.app.bootstrap.elements import input_box
|
|
12
12
|
from runtimepy.net.server.app.bootstrap.tabs import TabbedContent
|
|
13
13
|
from runtimepy.net.server.app.env.modal import Modal
|
|
14
|
+
from runtimepy.net.server.app.env.settings import plot_settings
|
|
14
15
|
from runtimepy.net.server.app.env.tab import ChannelEnvironmentTab
|
|
15
16
|
from runtimepy.net.server.app.placeholder import dummy_tabs, under_construction
|
|
16
17
|
from runtimepy.net.server.app.sound import SoundTab
|
|
@@ -85,8 +86,7 @@ def channel_environments(app: AppInfo, tabs: TabbedContent) -> None:
|
|
|
85
86
|
)
|
|
86
87
|
|
|
87
88
|
# Plot settings modal.
|
|
88
|
-
plot_settings
|
|
89
|
-
under_construction(plot_settings.footer)
|
|
89
|
+
plot_settings(tabs)
|
|
90
90
|
|
|
91
91
|
# Experimental features.
|
|
92
92
|
if app.config_param("experimental", False):
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A module implementing an application-settings modal.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# third-party
|
|
6
|
+
from svgen.element.html import div
|
|
7
|
+
|
|
8
|
+
# internal
|
|
9
|
+
from runtimepy.net.server.app.bootstrap.elements import flex, slider
|
|
10
|
+
from runtimepy.net.server.app.bootstrap.tabs import TabbedContent
|
|
11
|
+
from runtimepy.net.server.app.env.modal import Modal
|
|
12
|
+
from runtimepy.net.server.app.placeholder import under_construction
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def plot_settings(tabs: TabbedContent) -> None:
|
|
16
|
+
"""Create the plot settings modal."""
|
|
17
|
+
|
|
18
|
+
modal = Modal(tabs, name="plot", icon="graph-up")
|
|
19
|
+
under_construction(modal.footer)
|
|
20
|
+
|
|
21
|
+
div(tag="h1", text="settings", parent=modal.body)
|
|
22
|
+
div(tag="hr", parent=modal.body)
|
|
23
|
+
|
|
24
|
+
div(tag="h2", text="plot status", parent=modal.body)
|
|
25
|
+
div(id="plot-status-inner", parent=modal.body)
|
|
26
|
+
div(tag="hr", parent=modal.body)
|
|
27
|
+
|
|
28
|
+
div(tag="h2", text="minimum transmit period (ms)", parent=modal.body)
|
|
29
|
+
|
|
30
|
+
div(
|
|
31
|
+
tag="p",
|
|
32
|
+
text=(
|
|
33
|
+
"Can be used to throttle the rate of "
|
|
34
|
+
"client <-> server communication. Use the 'ui' tab's metrics to "
|
|
35
|
+
"determine performance impact. Note that only this browser tab's "
|
|
36
|
+
"messaging rate can be controlled (not other connected clients')."
|
|
37
|
+
),
|
|
38
|
+
parent=modal.body,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
container = flex(parent=modal.body)
|
|
42
|
+
|
|
43
|
+
div(
|
|
44
|
+
text="0 ms ('high', run at native refresh rate)",
|
|
45
|
+
parent=container,
|
|
46
|
+
class_str="text-nowrap text-primary",
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
slider(
|
|
50
|
+
0, 100, 100, parent=container, value=0, id="setting-min-tx-period-ms"
|
|
51
|
+
).add_class("ms-3 me-3")
|
|
52
|
+
|
|
53
|
+
div(
|
|
54
|
+
text="100 ms ('low', 10 Hz)",
|
|
55
|
+
parent=container,
|
|
56
|
+
class_str="text-nowrap text-primary",
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
div(tag="hr", parent=modal.body)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
A module implementing SSL-related interfaces.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
# built-in
|
|
6
|
+
import ssl
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def handle_possible_ssl(client: bool = True, **kwargs) -> dict[str, Any]:
|
|
11
|
+
"""Handle creating an SSL context based on keyword arguments."""
|
|
12
|
+
|
|
13
|
+
args = ["cafile", "capath", "cadata"]
|
|
14
|
+
if (
|
|
15
|
+
kwargs.pop("use_ssl", False)
|
|
16
|
+
or any(x in kwargs for x in args)
|
|
17
|
+
or "certfile" in kwargs
|
|
18
|
+
):
|
|
19
|
+
context = ssl.create_default_context(
|
|
20
|
+
purpose=(
|
|
21
|
+
ssl.Purpose.SERVER_AUTH if client else ssl.Purpose.CLIENT_AUTH
|
|
22
|
+
),
|
|
23
|
+
**{x: kwargs.pop(x, None) for x in args},
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
if "certfile" in kwargs:
|
|
27
|
+
context.load_cert_chain(
|
|
28
|
+
kwargs.pop("certfile"), keyfile=kwargs.pop("keyfile", None)
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
kwargs["ssl"] = context
|
|
32
|
+
|
|
33
|
+
return kwargs
|