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%",
}}
>
+
+
);
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
),