diff --git a/pyproject.toml b/pyproject.toml index 9e8d9bfc6..1c496285e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,8 @@ dependencies = [ "nodeenv>=1.8.0", "psutil>=5.9.5", "yourdfpy>=0.0.53", - "plyfile>=1.0.2" + "plyfile>=1.0.2", + "cryptography>=44.0.2", ] [project.optional-dependencies] diff --git a/src/viser/_certificates.py b/src/viser/_certificates.py new file mode 100644 index 000000000..e4784dc80 --- /dev/null +++ b/src/viser/_certificates.py @@ -0,0 +1,50 @@ +import tempfile + + +def create_self_signed_cert(): + """Generates a self-signed SSL certificate and key.""" + import datetime + + from cryptography import x509 + from cryptography.hazmat.primitives import hashes, serialization + from cryptography.hazmat.primitives.asymmetric import rsa + from cryptography.x509.oid import NameOID + + key = rsa.generate_private_key(public_exponent=65537, key_size=2048) + subject = issuer = x509.Name( + [ + x509.NameAttribute(NameOID.COUNTRY_NAME, "US"), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "California"), + x509.NameAttribute(NameOID.LOCALITY_NAME, "San Francisco"), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "My Fake SSL"), + x509.NameAttribute(NameOID.COMMON_NAME, "localhost"), + ] + ) + cert = ( + x509.CertificateBuilder() + .subject_name(subject) + .issuer_name(issuer) + .public_key(key.public_key()) + .serial_number(x509.random_serial_number()) + .not_valid_before(datetime.datetime.utcnow()) + .not_valid_after(datetime.datetime.utcnow() + datetime.timedelta(days=365)) + .add_extension(x509.BasicConstraints(ca=True, path_length=None), critical=True) + .sign(key, hashes.SHA256()) + ) + + cert_path = tempfile.NamedTemporaryFile(delete=False, suffix=".crt").name + key_path = tempfile.NamedTemporaryFile(delete=False, suffix=".key").name + + with open(cert_path, "wb") as f: + f.write(cert.public_bytes(serialization.Encoding.PEM)) + + with open(key_path, "wb") as f: + f.write( + key.private_bytes( + serialization.Encoding.PEM, + serialization.PrivateFormat.TraditionalOpenSSL, + serialization.NoEncryption(), + ) + ) + + return cert_path, key_path diff --git a/src/viser/_viser.py b/src/viser/_viser.py index 1da8cc746..d8569c915 100644 --- a/src/viser/_viser.py +++ b/src/viser/_viser.py @@ -23,6 +23,7 @@ from . import _client_autobuild, _messages, infra from . import transforms as tf +from ._certificates import create_self_signed_cert from ._gui_api import Color, GuiApi, _make_uuid from ._notification_handle import NotificationHandle, _NotificationHandleState from ._scene_api import SceneApi, cast_vector @@ -588,6 +589,8 @@ class ViserServer(_BackwardsCompatibilityShim if not TYPE_CHECKING else object): host: Host to bind server to. port: Port to bind server to. label: Label shown at the top of the GUI panel. + https: Whether to use HTTPS with self-signed certificates. If True, + server will use HTTPS and WSS protocols. """ # Hide deprecated arguments from docstring and type checkers. @@ -597,8 +600,20 @@ def __init__( port: int = 8080, label: str | None = None, verbose: bool = True, + https: bool = False, **_deprecated_kwargs, ): + ssl_context = None + if https: + # Create Self Signed Certificates + cert_path, key_path = create_self_signed_cert() + + # Create SSL Context + import ssl + + ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + ssl_context.load_cert_chain(cert_path, key_path) + # Create server. server = infra.WebsockServer( host=host, @@ -607,6 +622,7 @@ def __init__( http_server_root=Path(__file__).absolute().parent / "client" / "build", verbose=verbose, client_api_version=1, + ssl_context=ssl_context, ) self._websock_server = server @@ -728,19 +744,23 @@ def request_share_url_no_return() -> None: # To suppress type error. # 0.0.0.0 is not a real IP and people are often confused by it; # we'll just print localhost. This is questionable from a security # perspective, but probably fine for our use cases. - http_url = f"http://localhost:{port}" - ws_url = f"ws://localhost:{port}" + http_protocol = "https" if https else "http" + ws_protocol = "wss" if https else "ws" + http_url = f"{http_protocol}://localhost:{port}" + ws_url = f"{ws_protocol}://localhost:{port}" else: - http_url = f"http://{host}:{port}" - ws_url = f"ws://{host}:{port}" + http_protocol = "https" if https else "http" + ws_protocol = "wss" if https else "ws" + http_url = f"{http_protocol}://{host}:{port}" + ws_url = f"{ws_protocol}://{host}:{port}" table = Table( title=None, show_header=False, box=box.MINIMAL, title_style=style.Style(bold=True), ) - table.add_row("HTTP", http_url) - table.add_row("Websocket", ws_url) + table.add_row(http_protocol.upper(), http_url) + table.add_row(ws_protocol.upper(), ws_url) rich.print( Panel( table, diff --git a/src/viser/client/package.json b/src/viser/client/package.json index 5dcff01ab..b7674d4ff 100644 --- a/src/viser/client/package.json +++ b/src/viser/client/package.json @@ -14,6 +14,7 @@ "@msgpack/msgpack": "^3.0.0-beta2", "@react-three/drei": "^9.64.0", "@react-three/fiber": "^8.12.0", + "@react-three/xr": "^6.6.9", "@tabler/icons-react": "^3.1.0", "@types/node": "^20.11.30", "@types/react": "^18.0.33", diff --git a/src/viser/client/src/App.tsx b/src/viser/client/src/App.tsx index 97680b13d..df7a9c140 100644 --- a/src/viser/client/src/App.tsx +++ b/src/viser/client/src/App.tsx @@ -48,6 +48,14 @@ import { AutoShadowDirectionalLight } from "./ThreeAssets"; THREE.ColorManagement.enabled = true; +// VR related imports +import { Canvas } from "@react-three/fiber"; +import { XR, createXRStore } from "@react-three/xr"; +import { useState } from "react"; + +const store = createXRStore(); +// End VR related imports + function ViewerRoot() { // What websocket server should we connect to? function getDefaultServerFromUrl() { @@ -242,6 +250,8 @@ function ViewerCanvas({ children }: { children: React.ReactNode }) { height: "100%", }} > + + - {inView ? null : } - - - {memoizedCameraControls} - - - {children} - - - + + {inView ? null : } + + + {memoizedCameraControls} + + + {children} + + + + ); diff --git a/src/viser/client/vite.config.mts b/src/viser/client/vite.config.mts index 52d94f0d8..854b789f9 100644 --- a/src/viser/client/vite.config.mts +++ b/src/viser/client/vite.config.mts @@ -1,7 +1,6 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import { vanillaExtractPlugin } from "@vanilla-extract/vite-plugin"; - import viteTsconfigPaths from "vite-tsconfig-paths"; import svgrPlugin from "vite-plugin-svgr"; import eslint from "vite-plugin-eslint"; diff --git a/src/viser/client/yarn.lock b/src/viser/client/yarn.lock index 2ee1ffed4..24575e7c3 100644 --- a/src/viser/client/yarn.lock +++ b/src/viser/client/yarn.lock @@ -177,11 +177,33 @@ "@babel/helper-string-parser" "^7.25.9" "@babel/helper-validator-identifier" "^7.25.9" +"@bufbuild/protobuf@^2.0.0": + version "2.2.4" + resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-2.2.4.tgz#4f43b3e775ce0bf7a9a84b547f017105db3c184d" + integrity sha512-P9xQgtMh71TA7tHTnbDe68zcI+TPnkyyfBIhGaUr4iUEIXN7yI01DyjmmdEwXTk5OlISBJYkoxCVj2dwmHqIkA== + "@emotion/hash@^0.9.0": version "0.9.2" resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b" integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== +"@emotion/is-prop-valid@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz#d4175076679c6a26faa92b03bb786f9e52612337" + integrity sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw== + dependencies: + "@emotion/memoize" "^0.8.1" + +"@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + +"@emotion/unitless@0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== + "@esbuild/aix-ppc64@0.21.5": version "0.21.5" resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" @@ -485,6 +507,32 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.9.tgz#50dea3616bc8191fb8e112283b49eaff03e78429" integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg== +"@fortawesome/fontawesome-common-types@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz#31ab07ca6a06358c5de4d295d4711b675006163f" + integrity sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw== + +"@fortawesome/fontawesome-svg-core@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz#2a24c32ef92136e98eae2ff334a27145188295ff" + integrity sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg== + dependencies: + "@fortawesome/fontawesome-common-types" "6.6.0" + +"@fortawesome/free-solid-svg-icons@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz#061751ca43be4c4d814f0adbda8f006164ec9f3b" + integrity sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA== + dependencies: + "@fortawesome/fontawesome-common-types" "6.6.0" + +"@fortawesome/react-fontawesome@0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz#68b058f9132b46c8599875f6a636dad231af78d4" + integrity sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g== + dependencies: + prop-types "^15.8.1" + "@humanwhocodes/config-array@^0.13.0": version "0.13.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" @@ -504,6 +552,29 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@iwer/devui@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@iwer/devui/-/devui-1.1.1.tgz#90a8c91b0cade72419c85ee86ae97c42a72ab558" + integrity sha512-S+m+qf9ih7LiSlmMpPProBySt6fV/G5iF/axv1pl0wmgiZVtJNnUV0Ezt0jarBNonZ2wXD9sqrf/JwjgLqXE6g== + dependencies: + "@fortawesome/fontawesome-svg-core" "6.6.0" + "@fortawesome/free-solid-svg-icons" "6.6.0" + "@fortawesome/react-fontawesome" "0.2.2" + "@pmndrs/handle" "^6.5.5" + "@pmndrs/pointer-events" "^6.5.5" + react "18.3.1" + react-dom "18.3.1" + styled-components "6.1.13" + three "^0.165.0" + +"@iwer/sem@~0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@iwer/sem/-/sem-0.2.5.tgz#c441c79f45f5d6f7aefb6f5a58370e2ba584267f" + integrity sha512-vMCfpu/7Qqc+hkBiGD9pxjeObgrhXOrL0KX94CA3yzJaU0dq0y49HXZT6fC+6X/jOmjaM3hjyE1m2h7ZmLzzyA== + dependencies: + three "^0.165.0" + ts-proto "^2.6.0" + "@jridgewell/gen-mapping@^0.3.5": version "0.3.8" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz#4f0e06362e01362f823d348f1872b08f666d8142" @@ -661,6 +732,31 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@pmndrs/handle@^6.5.5": + version "6.6.9" + resolved "https://registry.yarnpkg.com/@pmndrs/handle/-/handle-6.6.9.tgz#ad50e65e7954b905a6a10ba712b47f3b0b65a81d" + integrity sha512-gZuT/6V4PX9x7XEDeFbKm1xUAXRvlO9SfEZjFUrfQCunw+1FdAVYncpvPd/a0j5ZgSJLAOZ+d3cvP5SweLdVAw== + dependencies: + "@pmndrs/pointer-events" "~6.6.9" + zustand "^4.5.2" + +"@pmndrs/pointer-events@^6.5.5", "@pmndrs/pointer-events@~6.6.9": + version "6.6.9" + resolved "https://registry.yarnpkg.com/@pmndrs/pointer-events/-/pointer-events-6.6.9.tgz#0de86de5d6c94f677275bad808660bf651e76db2" + integrity sha512-EGE4GdnCwvargSFtEJjS1+drhz9jnIpm1Pcirj0JxC+KTASM4meQ0Ga/0RNA6Fd7Ms3hTCVyf5d1uE0Xm1I+hg== + +"@pmndrs/xr@~6.6.9": + version "6.6.9" + resolved "https://registry.yarnpkg.com/@pmndrs/xr/-/xr-6.6.9.tgz#c254dea292736a04f9981f906d0b10ab9600373e" + integrity sha512-vBQsRcMQCMbCu5r5BUxHgXJS1goo20GCA0Jvb43UPqwxvggCAPRgSZyGqvG+x4NPVcr0yW/rYGgPtBcihu4FAg== + dependencies: + "@iwer/devui" "^1.1.1" + "@iwer/sem" "~0.2.5" + "@pmndrs/pointer-events" "~6.6.9" + iwer "^2.0.1" + meshline "^3.3.1" + zustand "^4.5.2" + "@react-spring/animated@~9.7.5": version "9.7.5" resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.7.5.tgz#eb0373aaf99b879736b380c2829312dae3b05f28" @@ -752,6 +848,17 @@ suspend-react "^0.1.3" zustand "^3.7.1" +"@react-three/xr@^6.6.9": + version "6.6.9" + resolved "https://registry.yarnpkg.com/@react-three/xr/-/xr-6.6.9.tgz#976ff3a8fa78b0fff0cc6014653005e525bbb3f9" + integrity sha512-nbUSLXamPYVlYjcDRDDU1vUqXwvvxLSGKthGilA2sniSGc1Xjayie8JVX3faReEGcKjQf2+V5JKmYgQje1Fuvg== + dependencies: + "@pmndrs/pointer-events" "~6.6.9" + "@pmndrs/xr" "~6.6.9" + suspend-react "^0.1.3" + tunnel-rat "^0.1.2" + zustand "^4.5.2" + "@remix-run/router@1.21.1": version "1.21.1" resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.21.1.tgz#bf15274d3856c395402719fa6b1dc8cc5245aaf7" @@ -1179,6 +1286,11 @@ resolved "https://registry.yarnpkg.com/@types/stats.js/-/stats.js-0.17.3.tgz#705446e12ce0fad618557dd88236f51148b7a935" integrity sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ== +"@types/stylis@4.2.5": + version "4.2.5" + resolved "https://registry.yarnpkg.com/@types/stylis/-/stylis-4.2.5.tgz#1daa6456f40959d06157698a653a9ab0a70281df" + integrity sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw== + "@types/three@*": version "0.172.0" resolved "https://registry.yarnpkg.com/@types/three/-/three-0.172.0.tgz#5094852dfa781d2fe1c65eb1b4985a4aa99858b7" @@ -1381,6 +1493,11 @@ dependencies: "@vanilla-extract/integration" "^7.1.12" +"@vitejs/plugin-basic-ssl@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.0.0.tgz#9169bfe748743b8806553e0d1aa78e8227c27b2d" + integrity sha512-gc9Tjg8bUxBVSTzeWT3Njc0Cl3PakHFKdNfABnZWiUgbxqmHDEn7uECv3fHVylxoYgNzAcmU7ZrILz+BwSo3sA== + "@vitejs/plugin-react@^4.0.1": version "4.3.4" resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.3.4.tgz#c64be10b54c4640135a5b28a2432330e88ad7c20" @@ -1647,6 +1764,11 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +camelize@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.1.tgz#89b7e16884056331a35d6b5ad064332c91daa6c3" + integrity sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ== + camera-controls@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/camera-controls/-/camera-controls-2.9.0.tgz#c3f67e702c2b68ae87418ca047c867e6494be2e8" @@ -1657,6 +1779,11 @@ caniuse-lite@^1.0.30001688: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz#4585729d95e6b95be5b439da6ab55250cd125bf9" integrity sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A== +case-anything@^2.1.13: + version "2.1.13" + resolved "https://registry.yarnpkg.com/case-anything/-/case-anything-2.1.13.tgz#0cdc16278cb29a7fcdeb072400da3f342ba329e9" + integrity sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng== + ccount@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" @@ -1763,6 +1890,20 @@ cross-spawn@^7.0.1, cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" +css-color-keywords@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05" + integrity sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg== + +css-to-react-native@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-3.2.0.tgz#cdd8099f71024e149e4f6fe17a7d46ecd55f1e32" + integrity sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ== + dependencies: + camelize "^1.0.0" + css-color-keywords "^1.0.0" + postcss-value-parser "^4.0.2" + css-what@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" @@ -1773,7 +1914,7 @@ cssesc@^3.0.0: resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -csstype@^3.0.2, csstype@^3.0.7: +csstype@3.1.3, csstype@^3.0.2, csstype@^3.0.7: version "3.1.3" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== @@ -1889,6 +2030,11 @@ detect-gpu@^5.0.56: dependencies: webgl-constants "^1.1.1" +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== + detect-node-es@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/detect-node-es/-/detect-node-es-1.1.0.tgz#163acdf643330caa0b4cd7c21e7ee7755d6fa493" @@ -1938,6 +2084,13 @@ dot-case@^3.0.4: no-case "^3.0.4" tslib "^2.0.3" +dprint-node@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/dprint-node/-/dprint-node-1.0.8.tgz#a02470722d8208a7d7eb3704328afda1d6758625" + integrity sha512-iVKnUtYfGrYcW1ZAlfR/F59cUVL8QIhWoBJoSjkkdua/dkWIgjZfiLMeTjiB06X0ZLkQ0M2C1VbUj/CxkIf1zg== + dependencies: + detect-libc "^1.0.3" + draco3d@^1.4.1: version "1.5.7" resolved "https://registry.yarnpkg.com/draco3d/-/draco3d-1.5.7.tgz#94f9bce293eb8920c159dc91a4ce9124a9e899e0" @@ -2537,6 +2690,11 @@ get-symbol-description@^1.1.0: es-errors "^1.3.0" get-intrinsic "^1.2.6" +gl-matrix@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-3.4.3.tgz#fc1191e8320009fd4d20e9339595c6041ddc22c9" + integrity sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA== + glob-parent@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -3033,6 +3191,13 @@ its-fine@^1.0.6, its-fine@^1.2.5: dependencies: "@types/react-reconciler" "^0.28.0" +iwer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/iwer/-/iwer-2.0.1.tgz#138cec1b558468814ccf42b60c98b7839777c811" + integrity sha512-kNjh8DDWGSnbiK6jKcVLYVRLFCMBQ4+sVyHZ3La4EJYTCTY+Trrnagf6z3oCdNpC4OTiwcPdakunTAqZhoWK+A== + dependencies: + gl-matrix "^3.4.3" + javascript-stringify@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" @@ -3823,6 +3988,11 @@ ms@^2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +nanoid@^3.3.7: + version "3.3.10" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.10.tgz#7bc882237698ef787d5cbba109e3b0168ba6e7b1" + integrity sha512-vSJJTG+t/dIKAUhUDw/dLdZ9s//5OxcHqLaDWWrW4Cdq7o6tdLIczUkMXt2MBNmk6sJRZBZRXVixs7URY1CmIg== + nanoid@^3.3.8: version "3.3.8" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf" @@ -4083,6 +4253,20 @@ postcss-simple-vars@^7.0.0: resolved "https://registry.yarnpkg.com/postcss-simple-vars/-/postcss-simple-vars-7.0.1.tgz#836b3097a54dcd13dbd3c36a5dbdd512fad2954c" integrity sha512-5GLLXaS8qmzHMOjVxqkk1TZPf1jMqesiI7qLhnlyERalG0sMbHIbJqrcnrpmZdKCLglHnRHoEBB61RtGTsj++A== +postcss-value-parser@^4.0.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@8.4.38: + version "8.4.38" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.38.tgz#b387d533baf2054288e337066d81c6bee9db9e0e" + integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A== + dependencies: + nanoid "^3.3.7" + picocolors "^1.0.0" + source-map-js "^1.2.0" + postcss@^8.4.38, postcss@^8.4.43: version "8.5.1" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.1.tgz#e2272a1f8a807fafa413218245630b5db10a3214" @@ -4151,7 +4335,7 @@ react-composer@^5.0.3: dependencies: prop-types "^15.6.0" -react-dom@^18.2.0: +react-dom@18.3.1, react-dom@^18.2.0: version "18.3.1" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== @@ -4263,7 +4447,7 @@ react-transition-group@4.4.5: loose-envify "^1.4.0" prop-types "^15.6.2" -react@^18.2.0: +react@18.3.1, react@^18.2.0: version "18.3.1" resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== @@ -4575,6 +4759,11 @@ set-proto@^1.0.0: es-errors "^1.3.0" es-object-atoms "^1.0.0" +shallowequal@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" + integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -4640,7 +4829,7 @@ snake-case@^3.0.4: dot-case "^3.0.4" tslib "^2.0.3" -source-map-js@^1.2.1: +source-map-js@^1.2.0, source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== @@ -4754,6 +4943,26 @@ style-to-object@^1.0.0: dependencies: inline-style-parser "0.2.4" +styled-components@6.1.13: + version "6.1.13" + resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-6.1.13.tgz#2d777750b773b31469bd79df754a32479e9f475e" + integrity sha512-M0+N2xSnAtwcVAQeFEsGWFFxXDftHUD7XrKla06QbpUMmbmtFBMMTcKWvFXtWxuD5qQkB8iU5gk6QASlx2ZRMw== + dependencies: + "@emotion/is-prop-valid" "1.2.2" + "@emotion/unitless" "0.8.1" + "@types/stylis" "4.2.5" + css-to-react-native "3.2.0" + csstype "3.1.3" + postcss "8.4.38" + shallowequal "1.1.0" + stylis "4.3.2" + tslib "2.6.2" + +stylis@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.2.tgz#8f76b70777dd53eb669c6f58c997bf0a9972e444" + integrity sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg== + sugarss@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-4.0.1.tgz#128a783ed71ee0fc3b489ce1f7d5a89bc1e24383" @@ -4813,6 +5022,11 @@ three@0.170.0, three@^0.170.0: resolved "https://registry.yarnpkg.com/three/-/three-0.170.0.tgz#6087f97aab79e9e9312f9c89fcef6808642dfbb7" integrity sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ== +three@^0.165.0: + version "0.165.0" + resolved "https://registry.yarnpkg.com/three/-/three-0.165.0.tgz#43b93b9b56c71b7eeee6b531d737ab573633ccd1" + integrity sha512-cc96IlVYGydeceu0e5xq70H8/yoVT/tXBxV/W8A/U6uOq7DXc4/s1Mkmnu6SqoYGhSRWWYFOhVwvq6V0VtbplA== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -4855,11 +5069,40 @@ ts-api-utils@^1.3.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== +ts-poet@^6.7.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/ts-poet/-/ts-poet-6.11.0.tgz#b41085c4ebf329bc6293a7d610a105978982b41a" + integrity sha512-r5AGF8vvb+GjBsnqiTqbLhN1/U2FJt6BI+k0dfCrkKzWvUhNlwMmq9nDHuucHs45LomgHjZPvYj96dD3JawjJA== + dependencies: + dprint-node "^1.0.8" + +ts-proto-descriptors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ts-proto-descriptors/-/ts-proto-descriptors-2.0.0.tgz#3a0e301a91cc6e932ac8dd13f7e07caa8a032c43" + integrity sha512-wHcTH3xIv11jxgkX5OyCSFfw27agpInAd6yh89hKG6zqIXnjW9SYqSER2CVQxdPj4czeOhGagNvZBEbJPy7qkw== + dependencies: + "@bufbuild/protobuf" "^2.0.0" + +ts-proto@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/ts-proto/-/ts-proto-2.6.1.tgz#3f112534408ec85019fc9d26b8c0b4911d184f10" + integrity sha512-4LTT99MkwkF1+fIA0b2mZu/58Qlpq3Q1g53TwEMZZgR1w/uX00PoVT4Z8aKJxMw0LeKQD4s9NrJYsF27Clckrg== + dependencies: + "@bufbuild/protobuf" "^2.0.0" + case-anything "^2.1.13" + ts-poet "^6.7.0" + ts-proto-descriptors "2.0.0" + tsconfck@^3.0.3: version "3.1.4" resolved "https://registry.yarnpkg.com/tsconfck/-/tsconfck-3.1.4.tgz#de01a15334962e2feb526824339b51be26712229" integrity sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ== +tslib@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + tslib@^2.0.0, tslib@^2.0.3, tslib@^2.1.0: version "2.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" @@ -5282,7 +5525,7 @@ zustand@^3.7.1: resolved "https://registry.yarnpkg.com/zustand/-/zustand-3.7.2.tgz#7b44c4f4a5bfd7a8296a3957b13e1c346f42514d" integrity sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA== -zustand@^4.3.2, zustand@^4.3.7: +zustand@^4.3.2, zustand@^4.3.7, zustand@^4.5.2: version "4.5.6" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.6.tgz#6857d52af44874a79fb3408c9473f78367255c96" integrity sha512-ibr/n1hBzLLj5Y+yUcU7dYw8p6WnIVzdJbnX+1YpaScvZVF2ziugqHs+LAmHw4lWO9c/zRj+K1ncgWDQuthEdQ== diff --git a/src/viser/infra/_infra.py b/src/viser/infra/_infra.py index 1c60a6377..8d9bd2ae0 100644 --- a/src/viser/infra/_infra.py +++ b/src/viser/infra/_infra.py @@ -65,9 +65,9 @@ def _insert_message(self, message: Message) -> None: def insert_sleep(self, duration: float) -> None: """Insert a sleep into the recorded file. This can be useful for dynamic 3D data.""" - assert self._handler._record_handle is not None, ( - "serialize() was already called!" - ) + assert ( + self._handler._record_handle is not None + ), "serialize() was already called!" self._time += duration def serialize(self) -> bytes: @@ -78,9 +78,9 @@ def serialize(self) -> bytes: Returns: The recording as bytes. """ - assert self._handler._record_handle is not None, ( - "serialize() was already called!" - ) + assert ( + self._handler._record_handle is not None + ), "serialize() was already called!" import viser packed_bytes = msgspec.msgpack.encode( @@ -133,9 +133,9 @@ def unregister_handler( callback: Callable[[ClientId, TMessage], None | Coroutine] | None = None, ): """Unregister a handler for a particular message type.""" - assert message_cls in self._incoming_handlers, ( - "Tried to unregister a handler that hasn't been registered." - ) + assert ( + message_cls in self._incoming_handlers + ), "Tried to unregister a handler that hasn't been registered." if callback is None: self._incoming_handlers.pop(message_cls) else: @@ -228,6 +228,7 @@ def __init__( http_server_root: Path | None = None, verbose: bool = True, client_api_version: Literal[0, 1] = 0, + ssl_context=None, ): super().__init__() @@ -246,6 +247,7 @@ def __init__( self._verbose = verbose self._client_api_version: Literal[0, 1] = client_api_version self._background_event_loop: asyncio.AbstractEventLoop | None = None + self._ssl_context = ssl_context self._stop_event: asyncio.Event | None = None @@ -511,6 +513,7 @@ async def start_server() -> None: port_attempt, # Compression can be too slow for our use cases. compression=None, + ssl=self._ssl_context, process_request=( viser_http_server if http_server_root is not None else None ),