✨ Adds msgPack and update message protocol
This commit is contained in:
@@ -48,11 +48,13 @@
|
|||||||
"@niku/vite-env-caster": "^1.0.2",
|
"@niku/vite-env-caster": "^1.0.2",
|
||||||
"@sveltejs/adapter-auto": "^4.0.0",
|
"@sveltejs/adapter-auto": "^4.0.0",
|
||||||
"@tailwindcss/vite": "^4.0.12",
|
"@tailwindcss/vite": "^4.0.12",
|
||||||
|
"@types/msgpack-lite": "^0.1.11",
|
||||||
"chart.js": "^4.4.2",
|
"chart.js": "^4.4.2",
|
||||||
"compare-versions": "^6.1.0",
|
"compare-versions": "^6.1.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"daisyui": "^5.0.0",
|
"daisyui": "^5.0.0",
|
||||||
"jwt-decode": "^4.0.0",
|
"jwt-decode": "^4.0.0",
|
||||||
|
"msgpack-lite": "^0.1.26",
|
||||||
"nipplejs": "^0.10.1",
|
"nipplejs": "^0.10.1",
|
||||||
"svelte-dnd-list": "^0.1.8",
|
"svelte-dnd-list": "^0.1.8",
|
||||||
"svelte-modals": "^2.0.0",
|
"svelte-modals": "^2.0.0",
|
||||||
|
|||||||
Generated
+91
-32
@@ -13,10 +13,13 @@ importers:
|
|||||||
version: 1.1.2
|
version: 1.1.2
|
||||||
'@sveltejs/adapter-auto':
|
'@sveltejs/adapter-auto':
|
||||||
specifier: ^4.0.0
|
specifier: ^4.0.0
|
||||||
version: 4.0.0(@sveltejs/kit@2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))
|
version: 4.0.0(@sveltejs/kit@2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))
|
||||||
'@tailwindcss/vite':
|
'@tailwindcss/vite':
|
||||||
specifier: ^4.0.12
|
specifier: ^4.0.12
|
||||||
version: 4.0.12(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
version: 4.0.12(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
||||||
|
'@types/msgpack-lite':
|
||||||
|
specifier: ^0.1.11
|
||||||
|
version: 0.1.11
|
||||||
chart.js:
|
chart.js:
|
||||||
specifier: ^4.4.2
|
specifier: ^4.4.2
|
||||||
version: 4.4.2
|
version: 4.4.2
|
||||||
@@ -32,6 +35,9 @@ importers:
|
|||||||
jwt-decode:
|
jwt-decode:
|
||||||
specifier: ^4.0.0
|
specifier: ^4.0.0
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
|
msgpack-lite:
|
||||||
|
specifier: ^0.1.26
|
||||||
|
version: 0.1.26
|
||||||
nipplejs:
|
nipplejs:
|
||||||
specifier: ^0.10.1
|
specifier: ^0.10.1
|
||||||
version: 0.10.1
|
version: 0.10.1
|
||||||
@@ -65,13 +71,13 @@ importers:
|
|||||||
version: 1.49.1
|
version: 1.49.1
|
||||||
'@sveltejs/adapter-static':
|
'@sveltejs/adapter-static':
|
||||||
specifier: ^3.0.1
|
specifier: ^3.0.1
|
||||||
version: 3.0.1(@sveltejs/kit@2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))
|
version: 3.0.1(@sveltejs/kit@2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))
|
||||||
'@sveltejs/kit':
|
'@sveltejs/kit':
|
||||||
specifier: ^2.5.27
|
specifier: ^2.5.27
|
||||||
version: 2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
version: 2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
||||||
'@sveltejs/vite-plugin-svelte':
|
'@sveltejs/vite-plugin-svelte':
|
||||||
specifier: ^5.0.3
|
specifier: ^5.0.3
|
||||||
version: 5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
version: 5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
||||||
'@types/eslint':
|
'@types/eslint':
|
||||||
specifier: ^8.56.0
|
specifier: ^8.56.0
|
||||||
version: 8.56.0
|
version: 8.56.0
|
||||||
@@ -128,10 +134,10 @@ importers:
|
|||||||
version: 0.18.5
|
version: 0.18.5
|
||||||
vite:
|
vite:
|
||||||
specifier: ^6.2.1
|
specifier: ^6.2.1
|
||||||
version: 6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
version: 6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
||||||
vitest:
|
vitest:
|
||||||
specifier: ^1.2.0
|
specifier: ^1.2.0
|
||||||
version: 1.2.0(jsdom@24.0.0)(lightningcss@1.29.2)
|
version: 1.2.0(@types/node@24.0.12)(jsdom@24.0.0)(lightningcss@1.29.2)
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
@@ -760,6 +766,12 @@ packages:
|
|||||||
'@types/json-schema@7.0.15':
|
'@types/json-schema@7.0.15':
|
||||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||||
|
|
||||||
|
'@types/msgpack-lite@0.1.11':
|
||||||
|
resolution: {integrity: sha512-cdCZS/gw+jIN22I4SUZUFf1ZZfVv5JM1//Br/MuZcI373sxiy3eSSoiyLu0oz+BPatTbGGGBO5jrcvd0siCdTQ==}
|
||||||
|
|
||||||
|
'@types/node@24.0.12':
|
||||||
|
resolution: {integrity: sha512-LtOrbvDf5ndC9Xi+4QZjVL0woFymF/xSTKZKPgrrl7H7XoeDvnD+E2IclKVDyaK9UM756W/3BXqSU+JEHopA9g==}
|
||||||
|
|
||||||
'@types/semver@7.5.8':
|
'@types/semver@7.5.8':
|
||||||
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
|
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
|
||||||
|
|
||||||
@@ -1190,6 +1202,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
event-lite@0.1.3:
|
||||||
|
resolution: {integrity: sha512-8qz9nOz5VeD2z96elrEKD2U433+L3DWdUdDkOINLGOJvx1GsMBbMn0aCeu28y8/e85A6mCigBiFlYMnTBEGlSw==}
|
||||||
|
|
||||||
execa@5.1.1:
|
execa@5.1.1:
|
||||||
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
|
resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -1335,6 +1350,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
ieee754@1.2.1:
|
||||||
|
resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
|
||||||
|
|
||||||
ignore@5.3.1:
|
ignore@5.3.1:
|
||||||
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
|
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
@@ -1356,6 +1374,9 @@ packages:
|
|||||||
inherits@2.0.4:
|
inherits@2.0.4:
|
||||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||||
|
|
||||||
|
int64-buffer@0.1.10:
|
||||||
|
resolution: {integrity: sha512-v7cSY1J8ydZ0GyjUHqF+1bshJ6cnEVLo9EnjB8p+4HDRPZc9N5jjmvUV7NvEsqQOKyH0pmIBFWXVQbiS0+OBbA==}
|
||||||
|
|
||||||
is-binary-path@2.1.0:
|
is-binary-path@2.1.0:
|
||||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@@ -1394,6 +1415,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
|
resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
|
||||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||||
|
|
||||||
|
isarray@1.0.0:
|
||||||
|
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
||||||
|
|
||||||
isexe@2.0.0:
|
isexe@2.0.0:
|
||||||
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
|
||||||
|
|
||||||
@@ -1592,6 +1616,10 @@ packages:
|
|||||||
ms@2.1.3:
|
ms@2.1.3:
|
||||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||||
|
|
||||||
|
msgpack-lite@0.1.26:
|
||||||
|
resolution: {integrity: sha512-SZ2IxeqZ1oRFGo0xFGbvBJWMp3yLIY9rlIJyxy8CGrwZn1f0ZK4r6jV/AM1r0FZMDUkWkglOk/eeKIL9g77Nxw==}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
nanoid@3.3.7:
|
nanoid@3.3.7:
|
||||||
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
|
resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
|
||||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||||
@@ -2019,6 +2047,9 @@ packages:
|
|||||||
ufo@1.5.3:
|
ufo@1.5.3:
|
||||||
resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
|
resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==}
|
||||||
|
|
||||||
|
undici-types@7.8.0:
|
||||||
|
resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==}
|
||||||
|
|
||||||
universalify@0.2.0:
|
universalify@0.2.0:
|
||||||
resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
|
resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
|
||||||
engines: {node: '>= 4.0.0'}
|
engines: {node: '>= 4.0.0'}
|
||||||
@@ -2613,18 +2644,18 @@ snapshots:
|
|||||||
|
|
||||||
'@sinclair/typebox@0.27.8': {}
|
'@sinclair/typebox@0.27.8': {}
|
||||||
|
|
||||||
'@sveltejs/adapter-auto@4.0.0(@sveltejs/kit@2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))':
|
'@sveltejs/adapter-auto@4.0.0(@sveltejs/kit@2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/kit': 2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
'@sveltejs/kit': 2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
||||||
import-meta-resolve: 4.1.0
|
import-meta-resolve: 4.1.0
|
||||||
|
|
||||||
'@sveltejs/adapter-static@3.0.1(@sveltejs/kit@2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))':
|
'@sveltejs/adapter-static@3.0.1(@sveltejs/kit@2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/kit': 2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
'@sveltejs/kit': 2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
||||||
|
|
||||||
'@sveltejs/kit@2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))':
|
'@sveltejs/kit@2.17.3(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
'@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
||||||
'@types/cookie': 0.6.0
|
'@types/cookie': 0.6.0
|
||||||
cookie: 0.6.0
|
cookie: 0.6.0
|
||||||
devalue: 5.1.1
|
devalue: 5.1.1
|
||||||
@@ -2637,27 +2668,27 @@ snapshots:
|
|||||||
set-cookie-parser: 2.6.0
|
set-cookie-parser: 2.6.0
|
||||||
sirv: 3.0.1
|
sirv: 3.0.1
|
||||||
svelte: 5.20.4
|
svelte: 5.20.4
|
||||||
vite: 6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
vite: 6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
||||||
|
|
||||||
'@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))':
|
'@sveltejs/vite-plugin-svelte-inspector@4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
'@sveltejs/vite-plugin-svelte': 5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
||||||
debug: 4.4.0
|
debug: 4.4.0
|
||||||
svelte: 5.20.4
|
svelte: 5.20.4
|
||||||
vite: 6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
vite: 6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
'@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))':
|
'@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
'@sveltejs/vite-plugin-svelte-inspector': 4.0.1(@sveltejs/vite-plugin-svelte@5.0.3(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)))(svelte@5.20.4)(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
||||||
debug: 4.4.0
|
debug: 4.4.0
|
||||||
deepmerge: 4.3.1
|
deepmerge: 4.3.1
|
||||||
kleur: 4.1.5
|
kleur: 4.1.5
|
||||||
magic-string: 0.30.17
|
magic-string: 0.30.17
|
||||||
svelte: 5.20.4
|
svelte: 5.20.4
|
||||||
vite: 6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
vite: 6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
||||||
vitefu: 1.0.6(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
vitefu: 1.0.6(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -2714,13 +2745,13 @@ snapshots:
|
|||||||
'@tailwindcss/oxide-win32-arm64-msvc': 4.0.12
|
'@tailwindcss/oxide-win32-arm64-msvc': 4.0.12
|
||||||
'@tailwindcss/oxide-win32-x64-msvc': 4.0.12
|
'@tailwindcss/oxide-win32-x64-msvc': 4.0.12
|
||||||
|
|
||||||
'@tailwindcss/vite@4.0.12(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))':
|
'@tailwindcss/vite@4.0.12(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@tailwindcss/node': 4.0.12
|
'@tailwindcss/node': 4.0.12
|
||||||
'@tailwindcss/oxide': 4.0.12
|
'@tailwindcss/oxide': 4.0.12
|
||||||
lightningcss: 1.29.2
|
lightningcss: 1.29.2
|
||||||
tailwindcss: 4.0.12
|
tailwindcss: 4.0.12
|
||||||
vite: 6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
vite: 6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
||||||
|
|
||||||
'@tweenjs/tween.js@23.1.2': {}
|
'@tweenjs/tween.js@23.1.2': {}
|
||||||
|
|
||||||
@@ -2737,6 +2768,14 @@ snapshots:
|
|||||||
|
|
||||||
'@types/json-schema@7.0.15': {}
|
'@types/json-schema@7.0.15': {}
|
||||||
|
|
||||||
|
'@types/msgpack-lite@0.1.11':
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 24.0.12
|
||||||
|
|
||||||
|
'@types/node@24.0.12':
|
||||||
|
dependencies:
|
||||||
|
undici-types: 7.8.0
|
||||||
|
|
||||||
'@types/semver@7.5.8': {}
|
'@types/semver@7.5.8': {}
|
||||||
|
|
||||||
'@types/stats.js@0.17.3': {}
|
'@types/stats.js@0.17.3': {}
|
||||||
@@ -3259,6 +3298,8 @@ snapshots:
|
|||||||
|
|
||||||
esutils@2.0.3: {}
|
esutils@2.0.3: {}
|
||||||
|
|
||||||
|
event-lite@0.1.3: {}
|
||||||
|
|
||||||
execa@5.1.1:
|
execa@5.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
cross-spawn: 7.0.3
|
cross-spawn: 7.0.3
|
||||||
@@ -3414,6 +3455,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
safer-buffer: 2.1.2
|
safer-buffer: 2.1.2
|
||||||
|
|
||||||
|
ieee754@1.2.1: {}
|
||||||
|
|
||||||
ignore@5.3.1: {}
|
ignore@5.3.1: {}
|
||||||
|
|
||||||
import-fresh@3.3.0:
|
import-fresh@3.3.0:
|
||||||
@@ -3432,6 +3475,8 @@ snapshots:
|
|||||||
|
|
||||||
inherits@2.0.4: {}
|
inherits@2.0.4: {}
|
||||||
|
|
||||||
|
int64-buffer@0.1.10: {}
|
||||||
|
|
||||||
is-binary-path@2.1.0:
|
is-binary-path@2.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
binary-extensions: 2.3.0
|
binary-extensions: 2.3.0
|
||||||
@@ -3458,6 +3503,8 @@ snapshots:
|
|||||||
|
|
||||||
is-stream@3.0.0: {}
|
is-stream@3.0.0: {}
|
||||||
|
|
||||||
|
isarray@1.0.0: {}
|
||||||
|
|
||||||
isexe@2.0.0: {}
|
isexe@2.0.0: {}
|
||||||
|
|
||||||
jiti@2.4.2: {}
|
jiti@2.4.2: {}
|
||||||
@@ -3635,6 +3682,13 @@ snapshots:
|
|||||||
|
|
||||||
ms@2.1.3: {}
|
ms@2.1.3: {}
|
||||||
|
|
||||||
|
msgpack-lite@0.1.26:
|
||||||
|
dependencies:
|
||||||
|
event-lite: 0.1.3
|
||||||
|
ieee754: 1.2.1
|
||||||
|
int64-buffer: 0.1.10
|
||||||
|
isarray: 1.0.0
|
||||||
|
|
||||||
nanoid@3.3.7: {}
|
nanoid@3.3.7: {}
|
||||||
|
|
||||||
nanoid@3.3.8: {}
|
nanoid@3.3.8: {}
|
||||||
@@ -4010,6 +4064,8 @@ snapshots:
|
|||||||
|
|
||||||
ufo@1.5.3: {}
|
ufo@1.5.3: {}
|
||||||
|
|
||||||
|
undici-types@7.8.0: {}
|
||||||
|
|
||||||
universalify@0.2.0: {}
|
universalify@0.2.0: {}
|
||||||
|
|
||||||
unplugin-icons@0.18.5:
|
unplugin-icons@0.18.5:
|
||||||
@@ -4054,13 +4110,13 @@ snapshots:
|
|||||||
|
|
||||||
uzip@0.20201231.0: {}
|
uzip@0.20201231.0: {}
|
||||||
|
|
||||||
vite-node@1.2.0(lightningcss@1.29.2):
|
vite-node@1.2.0(@types/node@24.0.12)(lightningcss@1.29.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
cac: 6.7.14
|
cac: 6.7.14
|
||||||
debug: 4.4.0
|
debug: 4.4.0
|
||||||
pathe: 1.1.2
|
pathe: 1.1.2
|
||||||
picocolors: 1.0.1
|
picocolors: 1.0.1
|
||||||
vite: 5.4.14(lightningcss@1.29.2)
|
vite: 5.4.14(@types/node@24.0.12)(lightningcss@1.29.2)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@types/node'
|
- '@types/node'
|
||||||
- less
|
- less
|
||||||
@@ -4072,31 +4128,33 @@ snapshots:
|
|||||||
- supports-color
|
- supports-color
|
||||||
- terser
|
- terser
|
||||||
|
|
||||||
vite@5.4.14(lightningcss@1.29.2):
|
vite@5.4.14(@types/node@24.0.12)(lightningcss@1.29.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.21.5
|
esbuild: 0.21.5
|
||||||
postcss: 8.5.3
|
postcss: 8.5.3
|
||||||
rollup: 4.34.8
|
rollup: 4.34.8
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
|
'@types/node': 24.0.12
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
lightningcss: 1.29.2
|
lightningcss: 1.29.2
|
||||||
|
|
||||||
vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2):
|
vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.25.0
|
esbuild: 0.25.0
|
||||||
postcss: 8.5.3
|
postcss: 8.5.3
|
||||||
rollup: 4.34.8
|
rollup: 4.34.8
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
|
'@types/node': 24.0.12
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
jiti: 2.4.2
|
jiti: 2.4.2
|
||||||
lightningcss: 1.29.2
|
lightningcss: 1.29.2
|
||||||
yaml: 2.4.2
|
yaml: 2.4.2
|
||||||
|
|
||||||
vitefu@1.0.6(vite@6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)):
|
vitefu@1.0.6(vite@6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)):
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite: 6.2.1(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
vite: 6.2.1(@types/node@24.0.12)(jiti@2.4.2)(lightningcss@1.29.2)(yaml@2.4.2)
|
||||||
|
|
||||||
vitest@1.2.0(jsdom@24.0.0)(lightningcss@1.29.2):
|
vitest@1.2.0(@types/node@24.0.12)(jsdom@24.0.0)(lightningcss@1.29.2):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vitest/expect': 1.2.0
|
'@vitest/expect': 1.2.0
|
||||||
'@vitest/runner': 1.2.0
|
'@vitest/runner': 1.2.0
|
||||||
@@ -4116,10 +4174,11 @@ snapshots:
|
|||||||
strip-literal: 1.3.0
|
strip-literal: 1.3.0
|
||||||
tinybench: 2.8.0
|
tinybench: 2.8.0
|
||||||
tinypool: 0.8.4
|
tinypool: 0.8.4
|
||||||
vite: 5.4.14(lightningcss@1.29.2)
|
vite: 5.4.14(@types/node@24.0.12)(lightningcss@1.29.2)
|
||||||
vite-node: 1.2.0(lightningcss@1.29.2)
|
vite-node: 1.2.0(@types/node@24.0.12)(lightningcss@1.29.2)
|
||||||
why-is-node-running: 2.2.2
|
why-is-node-running: 2.2.2
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
|
'@types/node': 24.0.12
|
||||||
jsdom: 24.0.0
|
jsdom: 24.0.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- less
|
- less
|
||||||
|
|||||||
@@ -1,14 +1,41 @@
|
|||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
import msgpack from 'msgpack-lite';
|
||||||
|
|
||||||
const socketEvents = ['open', 'close', 'error', 'message', 'unresponsive'] as const;
|
const socketEvents = ['open', 'close', 'error', 'message', 'unresponsive'] as const;
|
||||||
type SocketEvent = (typeof socketEvents)[number];
|
type SocketEvent = (typeof socketEvents)[number];
|
||||||
|
|
||||||
|
type SocketMessage = [number, string?, unknown?];
|
||||||
|
|
||||||
|
let useBinary = false;
|
||||||
|
|
||||||
|
const decodeMessage = (data: string | ArrayBuffer): SocketMessage | null => {
|
||||||
|
useBinary = data instanceof ArrayBuffer;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (useBinary) {
|
||||||
|
return msgpack.decode(new Uint8Array(data as ArrayBuffer));
|
||||||
|
}
|
||||||
|
return JSON.parse(data as string);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Could not decode data: ${data} - ${error}`);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
const encodeMessage = (data: unknown) => {
|
||||||
|
try {
|
||||||
|
return useBinary ? msgpack.encode(data) : JSON.stringify(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Could not encode data: ${data} - ${error}`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
function createWebSocket() {
|
function createWebSocket() {
|
||||||
let listeners = new Map<string, Set<(data?: unknown) => void>>();
|
const listeners = new Map<string, Set<(data?: unknown) => void>>();
|
||||||
const { subscribe, set } = writable(false);
|
const { subscribe, set } = writable(false);
|
||||||
const reconnectTimeoutTime = 5000;
|
const reconnectTimeoutTime = 5000;
|
||||||
let unresponsiveTimeoutId: number;
|
let unresponsiveTimeoutId: ReturnType<typeof setTimeout>;
|
||||||
let reconnectTimeoutId: number;
|
let reconnectTimeoutId: ReturnType<typeof setTimeout>;
|
||||||
let ws: WebSocket;
|
let ws: WebSocket;
|
||||||
let socketUrl: string | URL;
|
let socketUrl: string | URL;
|
||||||
|
|
||||||
@@ -22,46 +49,38 @@ function createWebSocket() {
|
|||||||
set(false);
|
set(false);
|
||||||
clearTimeout(unresponsiveTimeoutId);
|
clearTimeout(unresponsiveTimeoutId);
|
||||||
clearTimeout(reconnectTimeoutId);
|
clearTimeout(reconnectTimeoutId);
|
||||||
listeners.get(reason)?.forEach((listener) => listener(event));
|
listeners.get(reason)?.forEach(listener => listener(event));
|
||||||
reconnectTimeoutId = setTimeout(connect, reconnectTimeoutTime);
|
reconnectTimeoutId = setTimeout(connect, reconnectTimeoutTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
function connect() {
|
function connect() {
|
||||||
ws = new WebSocket(socketUrl);
|
ws = new WebSocket(socketUrl);
|
||||||
ws.onopen = (ev) => {
|
ws.binaryType = 'arraybuffer';
|
||||||
|
ws.onopen = ev => {
|
||||||
|
ping();
|
||||||
|
useBinary = true;
|
||||||
|
ping();
|
||||||
set(true);
|
set(true);
|
||||||
clearTimeout(reconnectTimeoutId);
|
clearTimeout(reconnectTimeoutId);
|
||||||
listeners.get('open')?.forEach((listener) => listener(ev));
|
listeners.get('open')?.forEach(listener => listener(ev));
|
||||||
for (const event of listeners.keys()) {
|
for (const event of listeners.keys()) {
|
||||||
if (socketEvents.includes(event as SocketEvent)) continue;
|
if (socketEvents.includes(event as SocketEvent)) continue;
|
||||||
subscribeToEvent(event);
|
subscribeToEvent(event);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
ws.onmessage = (message) => {
|
ws.onmessage = frame => {
|
||||||
resetUnresponsiveCheck();
|
resetUnresponsiveCheck();
|
||||||
let data = message.data;
|
const message = decodeMessage(frame.data);
|
||||||
if (data instanceof ArrayBuffer) {
|
if (!message) return;
|
||||||
listeners.get('binary')?.forEach((listener) => listener(data));
|
const [_, event, payload = undefined] = message;
|
||||||
return;
|
if (event) listeners.get(event)?.forEach(listener => listener(payload));
|
||||||
}
|
|
||||||
data = data.substring(1);
|
|
||||||
|
|
||||||
if (!data) return;
|
|
||||||
|
|
||||||
let event = data.substring(data.indexOf('/') + 1, data.indexOf('['));
|
|
||||||
let payload = data.substring(data.indexOf('[') + 1, data.lastIndexOf(']'));
|
|
||||||
|
|
||||||
try {
|
|
||||||
payload = JSON.parse(payload);
|
|
||||||
} catch (error) {}
|
|
||||||
if (event) listeners.get(event)?.forEach((listener) => listener(payload));
|
|
||||||
};
|
};
|
||||||
ws.onerror = (ev) => disconnect('error', ev);
|
ws.onerror = ev => disconnect('error', ev);
|
||||||
ws.onclose = (ev) => disconnect('close', ev);
|
ws.onclose = ev => disconnect('close', ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unsubscribe(event: string, listener?: (data: any) => void) {
|
function unsubscribe(event: string, listener?: (data: unknown) => void) {
|
||||||
let eventListeners = listeners.get(event);
|
const eventListeners = listeners.get(event);
|
||||||
if (!eventListeners) return;
|
if (!eventListeners) return;
|
||||||
|
|
||||||
if (!eventListeners.size) {
|
if (!eventListeners.size) {
|
||||||
@@ -81,17 +100,36 @@ function createWebSocket() {
|
|||||||
|
|
||||||
function sendEvent(event: string, data: unknown) {
|
function sendEvent(event: string, data: unknown) {
|
||||||
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
||||||
ws.send(`2/${event}[${JSON.stringify(data)}]`);
|
send([2, event, data]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function unsubscribeToEvent(event: string) {
|
function unsubscribeToEvent(event: string) {
|
||||||
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
||||||
ws.send('1/' + event);
|
send([1, event]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function subscribeToEvent(event: string) {
|
function subscribeToEvent(event: string) {
|
||||||
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
||||||
ws.send('0/' + event);
|
send([0, event]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function send(data: unknown) {
|
||||||
|
if (!ws || ws.readyState !== WebSocket.OPEN) return;
|
||||||
|
const serialized = encodeMessage(data);
|
||||||
|
if (!serialized) {
|
||||||
|
console.error('Could not serialize data:', data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ws.send(serialized);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ping() {
|
||||||
|
const serialized = encodeMessage([4]);
|
||||||
|
if (!serialized) {
|
||||||
|
console.error('Could not serialize message');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ws.send(serialized);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -107,15 +145,15 @@ function createWebSocket() {
|
|||||||
eventListeners = new Set();
|
eventListeners = new Set();
|
||||||
listeners.set(event, eventListeners);
|
listeners.set(event, eventListeners);
|
||||||
}
|
}
|
||||||
eventListeners.add(listener as (data: any) => void);
|
eventListeners.add(listener as (data: unknown) => void);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribe(event, listener);
|
unsubscribe(event, listener as (data: unknown) => void);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
off: (event: string, listener?: (data: any) => void) => {
|
off: <T>(event: string, listener?: (data: T) => void) => {
|
||||||
unsubscribe(event, listener);
|
unsubscribe(event, listener as (data: unknown) => void);
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
servoAnglesOut,
|
servoAnglesOut,
|
||||||
socket,
|
socket,
|
||||||
location,
|
location,
|
||||||
useFeatureFlags
|
useFeatureFlags,
|
||||||
} from '$lib/stores';
|
} from '$lib/stores';
|
||||||
import type { Analytics, DownloadOTA } from '$lib/types/models';
|
import type { Analytics, DownloadOTA } from '$lib/types/models';
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -36,10 +36,10 @@
|
|||||||
|
|
||||||
addEventListeners();
|
addEventListeners();
|
||||||
|
|
||||||
outControllerData.subscribe(data => socket.sendEvent('input', { data }));
|
outControllerData.subscribe(data => socket.sendEvent('input', data));
|
||||||
mode.subscribe(data => socket.sendEvent('mode', { data }));
|
mode.subscribe(data => socket.sendEvent('mode', data));
|
||||||
servoAnglesOut.subscribe(data => socket.sendEvent('angles', { data }));
|
servoAnglesOut.subscribe(data => socket.sendEvent('angles', data));
|
||||||
kinematicData.subscribe(data => socket.sendEvent('position', { data }));
|
kinematicData.subscribe(data => socket.sendEvent('position', data));
|
||||||
});
|
});
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
@@ -117,8 +117,8 @@
|
|||||||
<div
|
<div
|
||||||
class="fixed inset-0 z-40 max-h-full max-w-full bg-black/20 backdrop-blur-sm"
|
class="fixed inset-0 z-40 max-h-full max-w-full bg-black/20 backdrop-blur-sm"
|
||||||
transition:fade
|
transition:fade
|
||||||
onclick={modals.closeAll}
|
onclick={modals.closeAll}>
|
||||||
></div>
|
</div>
|
||||||
{/snippet}
|
{/snippet}
|
||||||
</Modals>
|
</Modals>
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import SettingsCard from '$lib/components/SettingsCard.svelte';
|
import SettingsCard from '$lib/components/SettingsCard.svelte';
|
||||||
import { WiFi } from '$lib/components/icons';
|
import { WiFi } from '$lib/components/icons';
|
||||||
import { location, socket, useFeatureFlags } from '$lib/stores';
|
import { location, socket } from '$lib/stores';
|
||||||
|
|
||||||
const features = useFeatureFlags();
|
const update = async () => {
|
||||||
|
|
||||||
const update = () => {
|
|
||||||
const ws = $location ? $location : window.location.host;
|
const ws = $location ? $location : window.location.host;
|
||||||
socket.init(`ws://${ws}/api/ws/events`);
|
socket.init(`ws://${ws}/api/ws/events`);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,3 +6,6 @@ build_flags =
|
|||||||
-D SERVE_CONFIG_FILES
|
-D SERVE_CONFIG_FILES
|
||||||
-D CORS_ORIGIN=\"*\"
|
-D CORS_ORIGIN=\"*\"
|
||||||
-D ENABLE_CORS
|
-D ENABLE_CORS
|
||||||
|
|
||||||
|
-D USE_MSGPACK=1 ; Use either msgpack or json
|
||||||
|
-D USE_JSON=0 ; Use either msgpack or json
|
||||||
@@ -2,46 +2,6 @@
|
|||||||
|
|
||||||
SemaphoreHandle_t clientSubscriptionsMutex = xSemaphoreCreateMutex();
|
SemaphoreHandle_t clientSubscriptionsMutex = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
message_type_t char_to_message_type(char c) {
|
|
||||||
switch (c) {
|
|
||||||
case '0': return CONNECT;
|
|
||||||
case '1': return DISCONNECT;
|
|
||||||
case '2': return EVENT;
|
|
||||||
case '3': return PING;
|
|
||||||
case '4': return PONG;
|
|
||||||
case '5': return BINARY_EVENT;
|
|
||||||
default: throw std::invalid_argument("Invalid message type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *getEventName(const char *msg) {
|
|
||||||
const char *start = strchr(msg, '/');
|
|
||||||
if (!start) return nullptr;
|
|
||||||
start++;
|
|
||||||
const char *end = strchr(start, '[');
|
|
||||||
if (!end) return start;
|
|
||||||
|
|
||||||
static char eventName[32];
|
|
||||||
int len = end - start;
|
|
||||||
strncpy(eventName, start, len);
|
|
||||||
eventName[len] = '\0';
|
|
||||||
return eventName;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *getEventPayload(const char *msg) {
|
|
||||||
const char *start = strchr(msg + 2, '[');
|
|
||||||
const char *end = msg + strlen(msg) - 1;
|
|
||||||
if (*start == '[') {
|
|
||||||
start++;
|
|
||||||
}
|
|
||||||
int len = end - start;
|
|
||||||
if (len < 0) return nullptr;
|
|
||||||
char *payload = new char[len + 1];
|
|
||||||
strncpy(payload, start, len);
|
|
||||||
payload[len] = '\0';
|
|
||||||
return payload;
|
|
||||||
}
|
|
||||||
|
|
||||||
EventSocket::EventSocket() {
|
EventSocket::EventSocket() {
|
||||||
_socket.onOpen((std::bind(&EventSocket::onWSOpen, this, std::placeholders::_1)));
|
_socket.onOpen((std::bind(&EventSocket::onWSOpen, this, std::placeholders::_1)));
|
||||||
_socket.onClose(std::bind(&EventSocket::onWSClose, this, std::placeholders::_1));
|
_socket.onClose(std::bind(&EventSocket::onWSClose, this, std::placeholders::_1));
|
||||||
@@ -65,26 +25,51 @@ esp_err_t EventSocket::onFrame(PsychicWebSocketRequest *request, httpd_ws_frame
|
|||||||
ESP_LOGV("EventSocket", "ws[%s][%u] opcode[%d]", request->client()->remoteIP().toString().c_str(),
|
ESP_LOGV("EventSocket", "ws[%s][%u] opcode[%d]", request->client()->remoteIP().toString().c_str(),
|
||||||
request->client()->socket(), frame->type);
|
request->client()->socket(), frame->type);
|
||||||
|
|
||||||
if (frame->type != HTTPD_WS_TYPE_TEXT) {
|
JsonDocument doc;
|
||||||
ESP_LOGE("EventSocket", "Unsupported frame type");
|
|
||||||
|
#if USE_MSGPACK
|
||||||
|
if (frame->type != HTTPD_WS_TYPE_BINARY) {
|
||||||
|
ESP_LOGE("EventSocket", "Unsupported frame type: %d", frame->type);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
if (deserializeMsgPack(doc, frame->payload, frame->len)) {
|
||||||
ESP_LOGV("EventSocket", "Received message: %s", (char *)frame->payload);
|
ESP_LOGE("EventSocket", "Could not deserialize msgpack");
|
||||||
char *msg = (char *)frame->payload;
|
|
||||||
|
|
||||||
message_type_t message_type = char_to_message_type(msg[0]);
|
|
||||||
|
|
||||||
if (message_type == PING) {
|
|
||||||
ESP_LOGV("EventSocket", "Ping");
|
|
||||||
request->client()->sendMessage("3");
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
} else if (message_type == PONG) {
|
};
|
||||||
|
#else
|
||||||
|
if (frame->type != HTTPD_WS_TYPE_TEXT) {
|
||||||
|
ESP_LOGE("EventSocket", "Unsupported frame type: %d", frame->type);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
if (deserializeJson(doc, frame->payload, frame->len)) {
|
||||||
|
ESP_LOGE("EventSocket", "Could not deserialize json");
|
||||||
|
return ESP_OK;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
serializeJson(doc, Serial);
|
||||||
|
Serial.println();
|
||||||
|
|
||||||
|
auto msg = doc.as<JsonArray>();
|
||||||
|
|
||||||
|
message_type_t message_type = static_cast<message_type_t>(msg[0].as<uint8_t>());
|
||||||
|
|
||||||
|
if (message_type == PONG) {
|
||||||
ESP_LOGV("EventSocket", "Pong");
|
ESP_LOGV("EventSocket", "Pong");
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
} else if (message_type == PING) {
|
||||||
|
ESP_LOGV("EventSocket", "Ping");
|
||||||
|
#if USE_MSGPACK
|
||||||
|
const uint8_t out[] = {0x91, 0x04};
|
||||||
|
send(request->client(), reinterpret_cast<const char *>(out), sizeof(out));
|
||||||
|
#else
|
||||||
|
const char *out = "[4]";
|
||||||
|
send(request->client(), out, strlen(out));
|
||||||
|
#endif
|
||||||
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *event = getEventName(msg);
|
const char *event = msg[1].as<const char *>();
|
||||||
|
|
||||||
if (!event) {
|
if (!event) {
|
||||||
ESP_LOGE("EventSocket", "Invalid event name");
|
ESP_LOGE("EventSocket", "Invalid event name");
|
||||||
@@ -99,18 +84,7 @@ esp_err_t EventSocket::onFrame(PsychicWebSocketRequest *request, httpd_ws_frame
|
|||||||
ESP_LOGV("EventSocket", "Disconnect: %s", event);
|
ESP_LOGV("EventSocket", "Disconnect: %s", event);
|
||||||
client_subscriptions[event].remove(request->client()->socket());
|
client_subscriptions[event].remove(request->client()->socket());
|
||||||
} else if (message_type == EVENT) {
|
} else if (message_type == EVENT) {
|
||||||
const char *payload = getEventPayload(msg);
|
JsonObject jsonObject = msg[2].as<JsonObject>();
|
||||||
if (!payload) {
|
|
||||||
ESP_LOGE("EventSocket", "Invalid event payload");
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
JsonDocument doc;
|
|
||||||
DeserializationError error = deserializeJson(doc, payload);
|
|
||||||
if (error) {
|
|
||||||
ESP_LOGE("EventSocket", "Failed to parse JSON payload");
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
JsonObject jsonObject = doc.as<JsonObject>();
|
|
||||||
handleEventCallbacks(event, jsonObject, request->client()->socket());
|
handleEventCallbacks(event, jsonObject, request->client()->socket());
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -127,8 +101,26 @@ void EventSocket::emit(const char *event, const char *payload, const char *origi
|
|||||||
xSemaphoreGive(clientSubscriptionsMutex);
|
xSemaphoreGive(clientSubscriptionsMutex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char msg[strlen(event) + strlen(payload) + 10];
|
|
||||||
snprintf(msg, sizeof(msg), "2/%s[%s]", event, payload);
|
JsonDocument doc;
|
||||||
|
auto a = doc.to<JsonArray>();
|
||||||
|
a.add(static_cast<uint8_t>(message_type_t::EVENT));
|
||||||
|
a.add(event);
|
||||||
|
|
||||||
|
JsonDocument payloadDoc;
|
||||||
|
if (deserializeJson(payloadDoc, payload) == DeserializationError::Ok)
|
||||||
|
a.add(payloadDoc.as<JsonVariant>());
|
||||||
|
else
|
||||||
|
a.add(payload); // fallback: insert as plain string if not valid JSON
|
||||||
|
|
||||||
|
String out;
|
||||||
|
#if USE_MSGPACK
|
||||||
|
serializeMsgPack(doc, out);
|
||||||
|
#else
|
||||||
|
serializeJson(doc, out);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *msg = out.c_str();
|
||||||
|
|
||||||
// if onlyToSameOrigin == true, send the message back to the origin
|
// if onlyToSameOrigin == true, send the message back to the origin
|
||||||
if (onlyToSameOrigin && originSubscriptionId > 0) {
|
if (onlyToSameOrigin && originSubscriptionId > 0) {
|
||||||
@@ -136,7 +128,7 @@ void EventSocket::emit(const char *event, const char *payload, const char *origi
|
|||||||
if (client) {
|
if (client) {
|
||||||
ESP_LOGV("EventSocket", "Emitting event: %s to %s, Message: %s", event,
|
ESP_LOGV("EventSocket", "Emitting event: %s to %s, Message: %s", event,
|
||||||
client->remoteIP().toString().c_str(), msg);
|
client->remoteIP().toString().c_str(), msg);
|
||||||
client->sendMessage(msg);
|
send(client, msg, strlen(msg));
|
||||||
}
|
}
|
||||||
} else { // else send the message to all other clients
|
} else { // else send the message to all other clients
|
||||||
|
|
||||||
@@ -149,12 +141,71 @@ void EventSocket::emit(const char *event, const char *payload, const char *origi
|
|||||||
}
|
}
|
||||||
ESP_LOGV("EventSocket", "Emitting event: %s to %s, Message: %s", event,
|
ESP_LOGV("EventSocket", "Emitting event: %s to %s, Message: %s", event,
|
||||||
client->remoteIP().toString().c_str(), msg);
|
client->remoteIP().toString().c_str(), msg);
|
||||||
client->sendMessage(msg);
|
send(client, msg, strlen(msg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xSemaphoreGive(clientSubscriptionsMutex);
|
xSemaphoreGive(clientSubscriptionsMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventSocket::emit(const char *event, JsonObject &payload, const char *originId, bool onlyToSameOrigin) {
|
||||||
|
int originSubscriptionId = originId[0] ? atoi(originId) : -1;
|
||||||
|
xSemaphoreTake(clientSubscriptionsMutex, portMAX_DELAY);
|
||||||
|
auto &subscriptions = client_subscriptions[event];
|
||||||
|
if (subscriptions.empty()) {
|
||||||
|
xSemaphoreGive(clientSubscriptionsMutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonDocument doc;
|
||||||
|
auto a = doc.to<JsonArray>();
|
||||||
|
a.add(static_cast<uint8_t>(message_type_t::EVENT));
|
||||||
|
a.add(event);
|
||||||
|
a.add(payload);
|
||||||
|
|
||||||
|
String out;
|
||||||
|
#if USE_MSGPACK
|
||||||
|
serializeMsgPack(doc, out);
|
||||||
|
#else
|
||||||
|
serializeJson(doc, out);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const char *msg = out.c_str();
|
||||||
|
|
||||||
|
// if onlyToSameOrigin == true, send the message back to the origin
|
||||||
|
if (onlyToSameOrigin && originSubscriptionId > 0) {
|
||||||
|
auto *client = _socket.getClient(originSubscriptionId);
|
||||||
|
if (client) {
|
||||||
|
ESP_LOGV("EventSocket", "Emitting event: %s to %s, Message: %s", event,
|
||||||
|
client->remoteIP().toString().c_str(), msg);
|
||||||
|
send(client, msg, strlen(msg));
|
||||||
|
}
|
||||||
|
} else { // else send the message to all other clients
|
||||||
|
|
||||||
|
for (int subscription : client_subscriptions[event]) {
|
||||||
|
if (subscription == originSubscriptionId) continue;
|
||||||
|
auto *client = _socket.getClient(subscription);
|
||||||
|
if (!client) {
|
||||||
|
subscriptions.remove(subscription);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ESP_LOGV("EventSocket", "Emitting event: %s to %s, Message: %s", event,
|
||||||
|
client->remoteIP().toString().c_str(), msg);
|
||||||
|
send(client, msg, strlen(msg));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xSemaphoreGive(clientSubscriptionsMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventSocket::send(PsychicWebSocketClient *client, const char *data, size_t len) {
|
||||||
|
if (!client) return;
|
||||||
|
|
||||||
|
#if USE_MSGPACK
|
||||||
|
client->sendMessage(HTTPD_WS_TYPE_BINARY, data, len);
|
||||||
|
#else
|
||||||
|
client->sendMessage(HTTPD_WS_TYPE_TEXT, data, len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void EventSocket::handleEventCallbacks(String event, JsonObject &jsonObject, int originId) {
|
void EventSocket::handleEventCallbacks(String event, JsonObject &jsonObject, int originId) {
|
||||||
for (auto &callback : event_callbacks[event]) {
|
for (auto &callback : event_callbacks[event]) {
|
||||||
callback(jsonObject, originId);
|
callback(jsonObject, originId);
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ class EventSocket {
|
|||||||
void onSubscribe(String event, SubscribeCallback callback);
|
void onSubscribe(String event, SubscribeCallback callback);
|
||||||
|
|
||||||
void emit(const char *event, const char *payload, const char *originId = "", bool onlyToSameOrigin = false);
|
void emit(const char *event, const char *payload, const char *originId = "", bool onlyToSameOrigin = false);
|
||||||
// if onlyToSameOrigin == true, the message will be sent to the originId only, otherwise it will be broadcasted to
|
|
||||||
// all clients except the originId
|
void emit(const char *event, JsonObject &root, const char *originId = "", bool onlyToSameOrigin = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PsychicWebSocketHandler _socket;
|
PsychicWebSocketHandler _socket;
|
||||||
@@ -35,6 +35,7 @@ class EventSocket {
|
|||||||
std::map<String, std::list<EventCallback>> event_callbacks;
|
std::map<String, std::list<EventCallback>> event_callbacks;
|
||||||
std::map<String, std::list<SubscribeCallback>> subscribe_callbacks;
|
std::map<String, std::list<SubscribeCallback>> subscribe_callbacks;
|
||||||
void handleEventCallbacks(String event, JsonObject &jsonObject, int originId);
|
void handleEventCallbacks(String event, JsonObject &jsonObject, int originId);
|
||||||
|
void send(PsychicWebSocketClient *client, const char *data, size_t len);
|
||||||
void handleSubscribeCallbacks(String event, const String &originId);
|
void handleSubscribeCallbacks(String event, const String &originId);
|
||||||
|
|
||||||
void onWSOpen(PsychicWebSocketClient *client);
|
void onWSOpen(PsychicWebSocketClient *client);
|
||||||
|
|||||||
@@ -67,6 +67,18 @@
|
|||||||
#define USE_MDNS 1
|
#define USE_MDNS 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// ESP32 MSGPACK on by default
|
||||||
|
#ifndef USE_MSGPACK
|
||||||
|
#define USE_MSGPACK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ESP32 JSON off by default
|
||||||
|
#ifndef USE_JSON
|
||||||
|
#define USE_JSON 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static_assert(!(USE_JSON == 1 && USE_MSGPACK == 1), "Cannot set both USE_JSON and USE_MSGPACK to 1 simultaneously");
|
||||||
|
|
||||||
namespace feature_service {
|
namespace feature_service {
|
||||||
|
|
||||||
void printFeatureConfiguration();
|
void printFeatureConfiguration();
|
||||||
|
|||||||
Reference in New Issue
Block a user