@velor/remote-mouse 6.4.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (316) hide show
  1. package/.artifacts/screenshots/remote-mobile-config.png +0 -0
  2. package/.artifacts/screenshots/remote-mobile-home.png +0 -0
  3. package/.artifacts/screenshots/remote-mobile-preferences.png +0 -0
  4. package/.artifacts/screenshots/remote-mobile-server-info.png +0 -0
  5. package/.artifacts/screenshots/remote-mobile-vlc.png +0 -0
  6. package/.env.example +93 -0
  7. package/README.md +370 -0
  8. package/bin/remote-mouse.js +19 -0
  9. package/client/core/dom.js +148 -0
  10. package/client/core/init-socket-io.js +117 -0
  11. package/client/core/socket-emit.js +6 -0
  12. package/client/core/window-events.js +23 -0
  13. package/client/i18n/apply-page-translations.js +18 -0
  14. package/client/i18n/constants.js +3 -0
  15. package/client/i18n/core.js +40 -0
  16. package/client/i18n/locale-registry.js +77 -0
  17. package/client/i18n/locales/de.js +227 -0
  18. package/client/i18n/locales/en.js +389 -0
  19. package/client/i18n/locales/es.js +228 -0
  20. package/client/i18n/locales/fr.js +389 -0
  21. package/client/i18n/locales/it.js +227 -0
  22. package/client/i18n/locales/ja.js +227 -0
  23. package/client/i18n/locales/pt.js +227 -0
  24. package/client/i18n/locales/ru.js +240 -0
  25. package/client/i18n/locales/zh.js +227 -0
  26. package/client/preferences/constants.js +15 -0
  27. package/client/preferences/effects.js +24 -0
  28. package/client/preferences/load.js +19 -0
  29. package/client/preferences/render.js +26 -0
  30. package/client/preferences/rows.js +78 -0
  31. package/client/preferences/state.js +29 -0
  32. package/client/preview/create-preview-frame-receiver.js +13 -0
  33. package/client/preview/draw.js +77 -0
  34. package/client/preview/parse-preview-frame.js +39 -0
  35. package/client/preview/preview-stream.js +152 -0
  36. package/client/services/app-state/appStateKeys.js +30 -0
  37. package/client/services/app-state/createAppStateService.js +216 -0
  38. package/client/services/app-state/createPersistStoreService.js +122 -0
  39. package/client/services/app-state/createStateStoreService.js +64 -0
  40. package/client/services/app-state/localStorageBinding.js +26 -0
  41. package/client/services/app-state/normalizers.js +74 -0
  42. package/client/services/app-state/resolveEffectiveStateValue.js +58 -0
  43. package/client/services/app-state/stateDefinitions.js +107 -0
  44. package/client/services/backend/createBackendService.js +55 -0
  45. package/client/services/config/ConfigView.js +45 -0
  46. package/client/services/config/createClientConfigService.js +122 -0
  47. package/client/services/config/defaultClientConfig.js +22 -0
  48. package/client/services/createServicesContainer.js +48 -0
  49. package/client/services/createServicesRegistry.js +26 -0
  50. package/client/services/i18n/createI18nService.js +86 -0
  51. package/client/services/notifications/createNotificationService.js +56 -0
  52. package/client/services/pubsub/createPubSubService.js +20 -0
  53. package/client/services/remotes/createRemotesService.js +20 -0
  54. package/client/services/transport/createSocketIoTransportService.js +50 -0
  55. package/client/touch/bindTouchPassthrough.js +94 -0
  56. package/client/touch/createTouchList.js +18 -0
  57. package/client/touch/dispatchSyntheticTouch.js +20 -0
  58. package/client/touch/gesture-zone.js +28 -0
  59. package/client/touch/throttle.js +46 -0
  60. package/client/touch/touch-handlers.js +193 -0
  61. package/client/touch/touchpad.js +231 -0
  62. package/client/ui/config/page.js +840 -0
  63. package/client/ui/main/applyRemoteVisibilityState.js +60 -0
  64. package/client/ui/main/bind-client-notifications.js +3 -0
  65. package/client/ui/main/bindings/bindAccordion.js +121 -0
  66. package/client/ui/main/bindings/bindActionButtons.js +13 -0
  67. package/client/ui/main/bindings/bindAdminDrawer.js +137 -0
  68. package/client/ui/main/bindings/bindAdminRemoteButtons.js +77 -0
  69. package/client/ui/main/bindings/bindAdminVersion.js +27 -0
  70. package/client/ui/main/bindings/bindBrowserRemoteButtons.js +119 -0
  71. package/client/ui/main/bindings/bindRemoteAccordion.js +23 -0
  72. package/client/ui/main/bindings/bindSamsungRemoteButtons.js +320 -0
  73. package/client/ui/main/bindings/bindSystemRemoteButtons.js +41 -0
  74. package/client/ui/main/bindings/bindVlcRemoteButtons.js +64 -0
  75. package/client/ui/main/canvas-ui.js +33 -0
  76. package/client/ui/main/connection-overlay.js +57 -0
  77. package/client/ui/main/init-ui.js +54 -0
  78. package/client/ui/main/keyboard-panel.js +271 -0
  79. package/client/ui/main/mouse-buttons.js +94 -0
  80. package/client/ui/main/page.js +21 -0
  81. package/client/ui/notifications/show-toast.js +48 -0
  82. package/client/ui/preferences/bindPreferenceSwitchers.js +49 -0
  83. package/client/ui/preferences/page.js +61 -0
  84. package/client/ui/preferences/switchers.js +200 -0
  85. package/index.js +9 -0
  86. package/package.json +41 -0
  87. package/public/admin-config.css +447 -0
  88. package/public/admin-config.html +63 -0
  89. package/public/apple-touch-icon.png +0 -0
  90. package/public/brave-icon.svg +13 -0
  91. package/public/favicon.svg +30 -0
  92. package/public/icon-192.png +0 -0
  93. package/public/icon-512.png +0 -0
  94. package/public/index.html +246 -0
  95. package/public/manifest.webmanifest +45 -0
  96. package/public/preferences.html +55 -0
  97. package/public/server-info.html +574 -0
  98. package/public/styles.css +1042 -0
  99. package/public/sw.js +103 -0
  100. package/scripts/codex-commit.sh +112 -0
  101. package/scripts/generate-mobile-screenshots.mjs +244 -0
  102. package/scripts/install-linux.sh +633 -0
  103. package/scripts/install-windows.ps1 +369 -0
  104. package/server/application/createApplicationLifecycle.js +15 -0
  105. package/server/application/logger.js +216 -0
  106. package/server/application/shutdown.js +81 -0
  107. package/server/application/start.js +95 -0
  108. package/server/application/state.js +19 -0
  109. package/server/connection/api/admin-actions.router.js +65 -0
  110. package/server/connection/api/admin-configs.router.js +165 -0
  111. package/server/connection/api/admin-remotes.router.js +61 -0
  112. package/server/connection/api/admin-subs.router.js +49 -0
  113. package/server/connection/api/client.router.js +15 -0
  114. package/server/connection/api/configs.js +96 -0
  115. package/server/connection/api/qr-page.handler.js +17 -0
  116. package/server/connection/api/remotes.router.js +30 -0
  117. package/server/connection/api/server-info.router.js +149 -0
  118. package/server/connection/api/session.middleware.js +93 -0
  119. package/server/connection/api/unauthorized-response.js +73 -0
  120. package/server/connection/socket/createConnectionRegistrar.js +23 -0
  121. package/server/connection/socket/createSocketSessionAuthMiddleware.js +49 -0
  122. package/server/connection/socket/socket-action-responder.js +12 -0
  123. package/server/connection/socket/socket.timestamp-middleware.js +51 -0
  124. package/server/index.js +12 -0
  125. package/server/init/bootstrapApi.js +87 -0
  126. package/server/init/bootstrapSocket.js +79 -0
  127. package/server/init/createAdminApiRouter.js +22 -0
  128. package/server/init/createAdminUiRouter.js +21 -0
  129. package/server/init/createSocketActionRegistrars.js +52 -0
  130. package/server/init/observers/startConfigObserver.js +51 -0
  131. package/server/init/observers/startDisplaySizeObserver.js +55 -0
  132. package/server/init/observers/startNotificationObserver.js +49 -0
  133. package/server/init/observers/startQrOverlayHoverObserver.js +89 -0
  134. package/server/init/observers/startQrOverlayRefreshObserver.js +53 -0
  135. package/server/os/darwin/app.js +45 -0
  136. package/server/os/darwin/applescript.js +51 -0
  137. package/server/os/darwin/cliSocket.js +53 -0
  138. package/server/os/darwin/url.js +9 -0
  139. package/server/os/darwin/window.js +10 -0
  140. package/server/os/linux/app.js +120 -0
  141. package/server/os/linux/cliSocket.js +53 -0
  142. package/server/os/linux/process.js +69 -0
  143. package/server/os/linux/screen.js +58 -0
  144. package/server/os/linux/systemd.js +139 -0
  145. package/server/os/linux/url.js +17 -0
  146. package/server/os/linux/windows.js +144 -0
  147. package/server/os/win32/app.js +66 -0
  148. package/server/os/win32/cliSocket.js +15 -0
  149. package/server/os/win32/powershell.js +70 -0
  150. package/server/os/win32/process.js +20 -0
  151. package/server/os/win32/service.js +95 -0
  152. package/server/os/win32/url.js +9 -0
  153. package/server/os/win32/window.js +10 -0
  154. package/server/remotes/admin/createAdminEventGuardMiddleware.js +29 -0
  155. package/server/remotes/admin/createForceUpdateCheckAction.js +39 -0
  156. package/server/remotes/admin/createInstallUpdateAction.js +64 -0
  157. package/server/remotes/admin/createOpenQrBrowserAction.js +63 -0
  158. package/server/remotes/admin/createOpenServerInfoBrowserAction.js +58 -0
  159. package/server/remotes/admin/createRestartServiceAction.js +20 -0
  160. package/server/remotes/admin/createRotateEntryTokenAction.js +43 -0
  161. package/server/remotes/admin/createToggleQrOverlayAction.js +38 -0
  162. package/server/remotes/admin/index.js +32 -0
  163. package/server/remotes/admin/notifyIfRestarted.js +102 -0
  164. package/server/remotes/admin/registrar.js +94 -0
  165. package/server/remotes/browser/actions/createFocusOrLaunchBrowserAction.js +22 -0
  166. package/server/remotes/browser/actions/openUrlOnHost.js +3 -0
  167. package/server/remotes/browser/browserCatalog.js +70 -0
  168. package/server/remotes/browser/index.js +15 -0
  169. package/server/remotes/browser/listBrowsersOnHost.js +23 -0
  170. package/server/remotes/browser/registrar.js +29 -0
  171. package/server/remotes/browser/spec.js +18 -0
  172. package/server/remotes/browser/state.js +5 -0
  173. package/server/remotes/input/registrar.js +39 -0
  174. package/server/remotes/preview/bgraToRgbaBuffer.js +20 -0
  175. package/server/remotes/preview/captureAroundCursor.js +19 -0
  176. package/server/remotes/preview/createPreviewStreamer.js +85 -0
  177. package/server/remotes/preview/registrar.js +34 -0
  178. package/server/remotes/samsung/createSamsungCommandService.js +203 -0
  179. package/server/remotes/samsung/createSamsungRemote.js +26 -0
  180. package/server/remotes/samsung/createSamsungRemoteGetter.js +46 -0
  181. package/server/remotes/samsung/createSamsungTvGetter.js +102 -0
  182. package/server/remotes/samsung/device-config.js +122 -0
  183. package/server/remotes/samsung/registrar.js +59 -0
  184. package/server/remotes/samsung/utils.js +56 -0
  185. package/server/remotes/vlc/index.js +39 -0
  186. package/server/remotes/vlc/registrar.js +94 -0
  187. package/server/remotes/vlc/spec.js +15 -0
  188. package/server/remotes/vlc/state.js +5 -0
  189. package/server/remotes/window/index.js +6 -0
  190. package/server/remotes/window/registrar.js +28 -0
  191. package/server/services/application/createApplicationDaemonService.js +144 -0
  192. package/server/services/application/getDaemonServiceAdapter.js +56 -0
  193. package/server/services/application/utils.js +29 -0
  194. package/server/services/config/bootstrapConfig.js +38 -0
  195. package/server/services/config/configPaths.js +42 -0
  196. package/server/services/config/configSchema.js +297 -0
  197. package/server/services/config/configService.js +89 -0
  198. package/server/services/config/defaultConfig.js +137 -0
  199. package/server/services/config/envConfig.js +49 -0
  200. package/server/services/config/index.js +9 -0
  201. package/server/services/config/logConfig.js +54 -0
  202. package/server/services/config/system-config.js +44 -0
  203. package/server/services/createServicesContainer.js +94 -0
  204. package/server/services/createServicesRegistry.js +48 -0
  205. package/server/services/input/createInputController.js +17 -0
  206. package/server/services/input/createKeyboardController.js +146 -0
  207. package/server/services/input/createMouseController.js +182 -0
  208. package/server/services/notifier/createClientNotifier.js +23 -0
  209. package/server/services/notifier/createHostNotifier.js +41 -0
  210. package/server/services/notifier/createNotifier.js +13 -0
  211. package/server/services/notifier/createNotifierComposite.js +122 -0
  212. package/server/services/notifier/handleOpenQrBrowserEvent.js +40 -0
  213. package/server/services/notifier/handleOpenServerInfoBrowserEvent.js +40 -0
  214. package/server/services/notifier/handleRestartServiceEvent.js +37 -0
  215. package/server/services/notifier/handleRotateEntryTokenEvent.js +42 -0
  216. package/server/services/notifier/handleSessionEvent.js +24 -0
  217. package/server/services/notifier/handleToggleQrOverlayEvent.js +21 -0
  218. package/server/services/notifier/host-notifier/createLinuxHostNotifier.js +23 -0
  219. package/server/services/notifier/host-notifier/createNodeNotifierHostNotifier.js +24 -0
  220. package/server/services/notifier/host-notifier/index.js +11 -0
  221. package/server/services/notifier/mapper/handleForceUpdateCheckEvent.js +24 -0
  222. package/server/services/notifier/mapper/handleInstallUpdateEvent.js +53 -0
  223. package/server/services/notifier/mapper/handleSocketEvent.js +40 -0
  224. package/server/services/notifier/mapper/handleUpdateManagerEvent.js +24 -0
  225. package/server/services/notifier/mapper/notify.js +7 -0
  226. package/server/services/os/index.js +23 -0
  227. package/server/services/os/platforms/createFallbackAdapter.js +31 -0
  228. package/server/services/os/platforms/darwin/app.js +6 -0
  229. package/server/services/os/platforms/darwin/index.js +21 -0
  230. package/server/services/os/platforms/darwin/scripts.js +4 -0
  231. package/server/services/os/platforms/darwin/url.js +1 -0
  232. package/server/services/os/platforms/darwin/window.js +4 -0
  233. package/server/services/os/platforms/linux/app.js +6 -0
  234. package/server/services/os/platforms/linux/index.js +33 -0
  235. package/server/services/os/platforms/linux/url.js +1 -0
  236. package/server/services/os/platforms/linux/windows.js +11 -0
  237. package/server/services/os/platforms/win32/app.js +6 -0
  238. package/server/services/os/platforms/win32/index.js +21 -0
  239. package/server/services/os/platforms/win32/overlay.js +6 -0
  240. package/server/services/os/platforms/win32/powershell.js +4 -0
  241. package/server/services/os/platforms/win32/url.js +1 -0
  242. package/server/services/os/platforms/win32/window.js +4 -0
  243. package/server/services/os/shared.js +2 -0
  244. package/server/services/overlay/createNoopOverlay.js +13 -0
  245. package/server/services/overlay/createQrOverlay.js +27 -0
  246. package/server/services/overlay/createQrOverlayWin32.js +158 -0
  247. package/server/services/overlay/createQrOverlayYad.js +178 -0
  248. package/server/services/overlay/renderQrPage.js +82 -0
  249. package/server/services/persistence/createConfigDao.js +106 -0
  250. package/server/services/persistence/createDatabaseProvider.js +23 -0
  251. package/server/services/persistence/createEntryTokenDao.js +140 -0
  252. package/server/services/persistence/createRestartLogDao.js +210 -0
  253. package/server/services/persistence/index.js +19 -0
  254. package/server/services/pubsub/createEventStore.js +54 -0
  255. package/server/services/pubsub/createPubSub.js +89 -0
  256. package/server/services/pubsub/createServiceEvents.js +29 -0
  257. package/server/services/pubsub/serviceEventConstants.js +39 -0
  258. package/server/services/remotes/createRemotes.js +25 -0
  259. package/server/services/server/createHttpsServer.js +12 -0
  260. package/server/services/server/createServer.js +66 -0
  261. package/server/services/sse/createSseService.js +96 -0
  262. package/server/services/sse/utils.js +7 -0
  263. package/server/services/system/createSystemService.js +170 -0
  264. package/server/services/system/getNetworkInfo.js +18 -0
  265. package/server/services/system/getScreenInfo.js +32 -0
  266. package/server/services/system/listNetworkInterfaces.js +27 -0
  267. package/server/services/task-manager/createTaskManager.js +68 -0
  268. package/server/services/task-runner/createTaskRunner.js +114 -0
  269. package/server/services/token-manager/createTokenManager.js +244 -0
  270. package/server/services/token-manager/token-format.js +7 -0
  271. package/server/services/token-manager/token-store-utils.js +8 -0
  272. package/server/services/update-manager/CommandUpdateSource.js +70 -0
  273. package/server/services/update-manager/NpmUpdateSource.js +34 -0
  274. package/server/services/update-manager/buildNpmGlobalUpdateCommand.js +15 -0
  275. package/server/services/update-manager/chooseUpdateCheckSource.js +20 -0
  276. package/server/services/update-manager/chooseUpdateInstallSource.js +5 -0
  277. package/server/services/update-manager/createUpdateManager.js +109 -0
  278. package/server/services/update-manager/resolveInstallUpdateCommand.js +42 -0
  279. package/server/term/cli/executeLocalServiceCommand.js +42 -0
  280. package/server/term/cli/getCliSocketPath.js +5 -0
  281. package/server/term/cli/parseCliArgs.js +110 -0
  282. package/server/term/cli/printCliResult.js +18 -0
  283. package/server/term/cli/runCliCmd.js +50 -0
  284. package/server/term/cli/sendCliCommand.js +76 -0
  285. package/server/term/cliSocket.js +29 -0
  286. package/server/term/srv/commands/configCommand.js +84 -0
  287. package/server/term/srv/commands/helpCommand.js +6 -0
  288. package/server/term/srv/commands/infoCommand.js +7 -0
  289. package/server/term/srv/commands/openQrCommand.js +7 -0
  290. package/server/term/srv/commands/samsungDetectCommand.js +52 -0
  291. package/server/term/srv/commands/serviceCommand.js +25 -0
  292. package/server/term/srv/commands/systemConfigCommand.js +7 -0
  293. package/server/term/srv/commands/tasksCommand.js +24 -0
  294. package/server/term/srv/commands/tokensCommand.js +15 -0
  295. package/server/term/srv/executeCliCommand.js +44 -0
  296. package/server/term/srv/executeCliRequest.js +38 -0
  297. package/server/term/srv/startCliServer.js +140 -0
  298. package/server/utils/createRandomToken.js +11 -0
  299. package/server/utils/env.js +155 -0
  300. package/server/utils/git.js +13 -0
  301. package/server/utils/http.js +7 -0
  302. package/server/utils/network.js +45 -0
  303. package/server/utils/paths.js +10 -0
  304. package/server/utils/process.js +57 -0
  305. package/server/utils/robot.js +11 -0
  306. package/server/utils/semver.js +33 -0
  307. package/server/utils/truncateText.js +7 -0
  308. package/utils/createLazy.js +13 -0
  309. package/utils/functional.js +48 -0
  310. package/utils/math.js +26 -0
  311. package/utils/notificationSettings.js +61 -0
  312. package/utils/object.utils.js +79 -0
  313. package/utils/predicates.js +17 -0
  314. package/utils/remoteCommands.js +40 -0
  315. package/utils/sync.js +3 -0
  316. package/velor-remote-mouse-6.4.8.tgz +0 -0
@@ -0,0 +1,86 @@
1
+ import {I18N_CHANGED_EVENT} from '../../i18n/constants.js';
2
+ import {interpolate, loadDictionary, resolveLocale} from '../../i18n/core.js';
3
+ import {applyPageTranslations} from '../../i18n/apply-page-translations.js';
4
+ import {createWindowEventListener, emitWindowEvent} from '../../core/window-events.js';
5
+
6
+ export function createI18nService(services) {
7
+ const onChange = createWindowEventListener(I18N_CHANGED_EVENT);
8
+ let currentLocale = '';
9
+ let currentDictionary = null;
10
+
11
+ function getResolvedLocale(value = typeof navigator !== 'undefined' ? navigator.language : '') {
12
+ return resolveLocale(value);
13
+ }
14
+
15
+ function applyLocaleToDom(locale) {
16
+ if (typeof document !== 'undefined') {
17
+ document.documentElement.lang = locale;
18
+ }
19
+ return locale;
20
+ }
21
+
22
+ function ensureInitialized() {
23
+ if (!currentLocale || !currentDictionary) {
24
+ throw new Error('Client i18n not initialized.');
25
+ }
26
+ }
27
+
28
+ function t(key, params = {}) {
29
+ ensureInitialized();
30
+ const template = currentDictionary[key] ?? key;
31
+ return interpolate(template, params);
32
+ }
33
+
34
+ function getI18nView() {
35
+ ensureInitialized();
36
+ return {
37
+ locale: currentLocale,
38
+ t,
39
+ };
40
+ }
41
+
42
+ return {
43
+ async init(locale) {
44
+ const normalizedLocale = getResolvedLocale(locale);
45
+ if (currentLocale === normalizedLocale && currentDictionary) {
46
+ return getI18nView();
47
+ }
48
+
49
+ currentDictionary = await loadDictionary(normalizedLocale);
50
+ currentLocale = normalizedLocale;
51
+ applyLocaleToDom(currentLocale);
52
+ return getI18nView();
53
+ },
54
+ getLocale() {
55
+ return getResolvedLocale(currentLocale);
56
+ },
57
+ getI18n() {
58
+ return getI18nView();
59
+ },
60
+ t(key, params) {
61
+ return t(key, params);
62
+ },
63
+ translateRoot(root = document) {
64
+ applyPageTranslations(root, t);
65
+ },
66
+ async setLocale(locale) {
67
+ const normalizedLocale = getResolvedLocale(locale);
68
+ const previousLocale = currentLocale || '';
69
+ await this.init(normalizedLocale);
70
+
71
+ applyPageTranslations(document, t);
72
+ emitWindowEvent(I18N_CHANGED_EVENT, {
73
+ locale: currentLocale,
74
+ previousLocale,
75
+ });
76
+
77
+ return getI18nView();
78
+ },
79
+ applyLocaleToDom(locale = currentLocale) {
80
+ return applyLocaleToDom(getResolvedLocale(locale));
81
+ },
82
+ onChange(listener) {
83
+ return onChange(listener);
84
+ },
85
+ };
86
+ }
@@ -0,0 +1,56 @@
1
+ import {REMOTE_EVENT_ADMIN_RESULT} from '../../../utils/remoteCommands.js';
2
+ import {showToast} from '../../ui/notifications/show-toast.js';
3
+
4
+ export function createNotificationService(services) {
5
+ const {getI18n, getPubSub, getTransport} = services;
6
+ let root = null;
7
+ let transportBound = false;
8
+ const queuedPayloads = [];
9
+
10
+ function flushQueue() {
11
+ if (!root) {
12
+ return;
13
+ }
14
+
15
+ while (queuedPayloads.length > 0) {
16
+ showToast(root, queuedPayloads.shift(), getI18n().t);
17
+ }
18
+ }
19
+
20
+ function notify(payload = {}) {
21
+ getPubSub().publish('notification.received', payload);
22
+
23
+ if (!root) {
24
+ queuedPayloads.push(payload);
25
+ return;
26
+ }
27
+
28
+ showToast(root, payload, getI18n().t);
29
+ }
30
+
31
+ function handleAdminResult(payload = {}) {
32
+ getPubSub().publish('admin.result.received', payload);
33
+
34
+ if (payload?.openUrl) {
35
+ window.open(String(payload.openUrl), '_blank', 'noopener,noreferrer');
36
+ }
37
+ }
38
+
39
+ return {
40
+ bindRoot(nextRoot) {
41
+ root = nextRoot || null;
42
+ flushQueue();
43
+ },
44
+ bindTransport() {
45
+ if (transportBound) {
46
+ return;
47
+ }
48
+
49
+ const transport = getTransport();
50
+ transport.on('notification', notify);
51
+ transport.on(REMOTE_EVENT_ADMIN_RESULT, handleAdminResult);
52
+ transportBound = true;
53
+ },
54
+ notify,
55
+ };
56
+ }
@@ -0,0 +1,20 @@
1
+ import {createWindowEventListener, emitWindowEvent} from '../../core/window-events.js';
2
+
3
+ let nextPubSubInstanceId = 1;
4
+
5
+ function toPubSubEventName(instanceId, eventName) {
6
+ return `client:pubsub:${instanceId}:${String(eventName || '').trim() || 'unknown'}`;
7
+ }
8
+
9
+ export function createPubSubService(services) {
10
+ const instanceId = nextPubSubInstanceId++;
11
+
12
+ return {
13
+ publish(eventName, payload = {}) {
14
+ emitWindowEvent(toPubSubEventName(instanceId, eventName), payload);
15
+ },
16
+ subscribe(eventName, listener) {
17
+ return createWindowEventListener(toPubSubEventName(instanceId, eventName))(listener);
18
+ },
19
+ };
20
+ }
@@ -0,0 +1,20 @@
1
+ export function createRemotesService(services) {
2
+ const {getBackend, getTransport, getPubSub} = services;
3
+ return {
4
+ emit(eventName, payload = {}) {
5
+ getTransport().emitWithTimestamp(eventName, payload);
6
+ },
7
+ async loadAvailableRemotes() {
8
+ const payload = await getBackend().getAvailableRemotes();
9
+ const remotes = Array.isArray(payload?.remotes) ? payload.remotes : [];
10
+ getPubSub().publish('remotes.available.changed', {remotes});
11
+ return remotes;
12
+ },
13
+ async loadAvailableBrowsers() {
14
+ const payload = await getBackend().getAvailableBrowsers();
15
+ const browsers = Array.isArray(payload?.browsers) ? payload.browsers : [];
16
+ getPubSub().publish('remotes.browsers.changed', {browsers});
17
+ return browsers;
18
+ },
19
+ };
20
+ }
@@ -0,0 +1,50 @@
1
+ import {initSocketIo} from '../../core/init-socket-io.js';
2
+
3
+ export function createSocketIoTransportService(services) {
4
+ const {getPubSub} = services;
5
+ let socket = null;
6
+
7
+ function ensureSocket() {
8
+ if (!socket) {
9
+ socket = initSocketIo();
10
+ getPubSub().publish('transport.connected-service', {transport: api});
11
+ }
12
+
13
+ return socket;
14
+ }
15
+
16
+ const api = {
17
+ connect() {
18
+ return ensureSocket();
19
+ },
20
+ getSocket() {
21
+ return ensureSocket();
22
+ },
23
+ emit(eventName, payload) {
24
+ ensureSocket().emit(eventName, payload);
25
+ },
26
+ emitWithTimestamp(eventName, payload = {}) {
27
+ ensureSocket().emit(eventName, {
28
+ ...payload,
29
+ ts: Date.now(),
30
+ });
31
+ },
32
+ on(eventName, handler) {
33
+ ensureSocket().on(eventName, handler);
34
+ return () => {
35
+ ensureSocket().off(eventName, handler);
36
+ };
37
+ },
38
+ once(eventName, handler) {
39
+ ensureSocket().once(eventName, handler);
40
+ },
41
+ off(eventName, handler) {
42
+ ensureSocket().off(eventName, handler);
43
+ },
44
+ get connected() {
45
+ return Boolean(socket?.connected);
46
+ },
47
+ };
48
+
49
+ return api;
50
+ }
@@ -0,0 +1,94 @@
1
+ import {dispatchSyntheticTouch} from "./dispatchSyntheticTouch.js";
2
+
3
+ const MOVE_THRESHOLD_PX = 10;
4
+
5
+ function distanceFrom(startTouch, nextTouch) {
6
+ const dx = nextTouch.clientX - startTouch.clientX;
7
+ const dy = nextTouch.clientY - startTouch.clientY;
8
+ return Math.hypot(dx, dy);
9
+ }
10
+
11
+ export function bindTouchPassthrough(buttons, touchpad) {
12
+ if (!touchpad) {
13
+ return;
14
+ }
15
+
16
+ for (const button of buttons || []) {
17
+ if (!button) {
18
+ continue;
19
+ }
20
+
21
+ let activeTouchId = null;
22
+ let startTouch = null;
23
+ let isPassthrough = false;
24
+ let suppressNextClick = false;
25
+
26
+ const resetState = () => {
27
+ activeTouchId = null;
28
+ startTouch = null;
29
+ isPassthrough = false;
30
+ };
31
+
32
+ const getTrackedTouch = (touchList) => Array.from(touchList || []).find((touch) => touch.identifier === activeTouchId);
33
+
34
+ const onTouchMove = (event) => {
35
+ const trackedTouch = getTrackedTouch(event.changedTouches) || getTrackedTouch(event.touches);
36
+ if (!trackedTouch || !startTouch) {
37
+ return;
38
+ }
39
+
40
+ const distance = distanceFrom(startTouch, trackedTouch);
41
+ if (!isPassthrough && distance < MOVE_THRESHOLD_PX) {
42
+ return;
43
+ }
44
+
45
+ if (!isPassthrough) {
46
+ isPassthrough = true;
47
+ suppressNextClick = true;
48
+ dispatchSyntheticTouch(touchpad, 'touchstart', startTouch);
49
+ }
50
+
51
+ event.preventDefault();
52
+ event.stopImmediatePropagation();
53
+ dispatchSyntheticTouch(touchpad, 'touchmove', trackedTouch);
54
+ };
55
+
56
+ const onTouchEnd = (event) => {
57
+ const trackedTouch = getTrackedTouch(event.changedTouches) || getTrackedTouch(event.touches) || startTouch;
58
+ if (isPassthrough && trackedTouch) {
59
+ event.preventDefault();
60
+ event.stopImmediatePropagation();
61
+ dispatchSyntheticTouch(touchpad, event.type === 'touchcancel' ? 'touchcancel' : 'touchend', trackedTouch);
62
+ }
63
+
64
+ resetState();
65
+ };
66
+
67
+ const onTouchStart = (event) => {
68
+ if (activeTouchId !== null || event.changedTouches.length !== 1) {
69
+ return;
70
+ }
71
+
72
+ const touch = event.changedTouches[0];
73
+ activeTouchId = touch.identifier;
74
+ startTouch = touch;
75
+ isPassthrough = false;
76
+ };
77
+
78
+ const onClickCapture = (event) => {
79
+ if (!suppressNextClick) {
80
+ return;
81
+ }
82
+
83
+ suppressNextClick = false;
84
+ event.preventDefault();
85
+ event.stopImmediatePropagation();
86
+ };
87
+
88
+ button.addEventListener('touchstart', onTouchStart, {passive: true});
89
+ button.addEventListener('click', onClickCapture, true);
90
+ document.addEventListener('touchmove', onTouchMove, {passive: false});
91
+ document.addEventListener('touchend', onTouchEnd, {passive: false});
92
+ document.addEventListener('touchcancel', onTouchEnd, {passive: false});
93
+ }
94
+ }
@@ -0,0 +1,18 @@
1
+ export function createTouchList(touchpad, touch) {
2
+ return [
3
+ new Touch({
4
+ identifier: touch.identifier,
5
+ target: touchpad,
6
+ clientX: touch.clientX,
7
+ clientY: touch.clientY,
8
+ screenX: touch.screenX ?? touch.clientX,
9
+ screenY: touch.screenY ?? touch.clientY,
10
+ pageX: touch.pageX ?? touch.clientX,
11
+ pageY: touch.pageY ?? touch.clientY,
12
+ radiusX: touch.radiusX ?? 1,
13
+ radiusY: touch.radiusY ?? 1,
14
+ rotationAngle: touch.rotationAngle ?? 0,
15
+ force: touch.force ?? 0.5,
16
+ }),
17
+ ];
18
+ }
@@ -0,0 +1,20 @@
1
+ import {createTouchList} from "./createTouchList.js";
2
+
3
+ export function dispatchSyntheticTouch(touchpad, type, sourceTouch) {
4
+ if (!touchpad || typeof Touch !== 'function' || typeof TouchEvent !== 'function') {
5
+ return;
6
+ }
7
+
8
+ const touches = type === 'touchend' || type === 'touchcancel'
9
+ ? []
10
+ : createTouchList(touchpad, sourceTouch);
11
+ const changedTouches = createTouchList(touchpad, sourceTouch);
12
+
13
+ touchpad.dispatchEvent(new TouchEvent(type, {
14
+ bubbles: true,
15
+ cancelable: true,
16
+ touches,
17
+ targetTouches: touches,
18
+ changedTouches,
19
+ }));
20
+ }
@@ -0,0 +1,28 @@
1
+ import { clamp } from '../../utils/math.js';
2
+
3
+ export function getScrollZoneWidth(width) {
4
+ return clamp(Math.round(width * 0.11), 36, 64);
5
+ }
6
+
7
+ export function getScrollZoneLayout(width, height, handedness = 'right') {
8
+ const edgeGap = clamp(Math.round(width * 0.012), 10, 14);
9
+ const zoneWidth = getScrollZoneWidth(width);
10
+ const isLeftHanded = String(handedness || '').toLowerCase() === 'left';
11
+ const x = isLeftHanded
12
+ ? edgeGap
13
+ : Math.max(0, width - zoneWidth - edgeGap);
14
+ const y = edgeGap;
15
+ const h = Math.max(24, height - edgeGap * 2);
16
+
17
+ return {
18
+ x,
19
+ y,
20
+ width: zoneWidth,
21
+ height: h,
22
+ edgeGap,
23
+ };
24
+ }
25
+
26
+ export function getRightScrollZoneLayout(width, height) {
27
+ return getScrollZoneLayout(width, height, 'right');
28
+ }
@@ -0,0 +1,46 @@
1
+ export function createAccumulatedThrottle(emitFn, intervalMs) {
2
+ let pendingDx = 0;
3
+ let pendingDy = 0;
4
+ let timer = null;
5
+ let lastFlushAt = 0;
6
+
7
+ function flush() {
8
+ timer = null;
9
+ if (pendingDx === 0 && pendingDy === 0) {
10
+ return;
11
+ }
12
+
13
+ const payload = { dx: pendingDx, dy: pendingDy };
14
+ pendingDx = 0;
15
+ pendingDy = 0;
16
+ lastFlushAt = Date.now();
17
+ emitFn(payload);
18
+ }
19
+
20
+ function schedule() {
21
+ if (timer) {
22
+ return;
23
+ }
24
+
25
+ const elapsed = Date.now() - lastFlushAt;
26
+ const delay = Math.max(0, intervalMs - elapsed);
27
+ timer = setTimeout(flush, delay);
28
+ }
29
+
30
+ function addDelta(dx, dy) {
31
+ pendingDx += dx;
32
+ pendingDy += dy;
33
+ schedule();
34
+ }
35
+
36
+ function flushNow() {
37
+ if (timer) {
38
+ clearTimeout(timer);
39
+ timer = null;
40
+ }
41
+ flush();
42
+ }
43
+
44
+ return { addDelta, flushNow };
45
+ }
46
+
@@ -0,0 +1,193 @@
1
+ import { getScrollZoneLayout } from './gesture-zone.js';
2
+ import {
3
+ applyNonLinearAcceleration,
4
+ distance2D,
5
+ scaleSigned,
6
+ } from '../../utils/math.js';
7
+
8
+ const SCROLL_GAIN = 1.1;
9
+ const REMOTE_HIDE_MOVEMENT_THRESHOLD_PX = 10;
10
+
11
+ function getDragHoldMs(handler) {
12
+ const value = Number(handler.getInputConfig?.().touchDragHoldMs);
13
+ return Number.isFinite(value) && value > 0 ? value : 420;
14
+ }
15
+
16
+ function getDragStillDistancePx(handler) {
17
+ const value = Number(handler.getInputConfig?.().touchDragStillDistancePx);
18
+ return Number.isFinite(value) && value > 0 ? value : 8;
19
+ }
20
+
21
+ function startDrag(state, handler) {
22
+ if (state.dragActive) {
23
+ return;
24
+ }
25
+
26
+ state.dragActive = true;
27
+ handler.buttonState('left', 'down');
28
+ }
29
+
30
+ function stopDrag(state, handler) {
31
+ if (!state.dragActive) {
32
+ return;
33
+ }
34
+
35
+ state.dragActive = false;
36
+ handler.buttonState('left', 'up');
37
+ }
38
+
39
+ function notifyMovementStartIfNeeded(state, handler, distancePx, kind = 'move') {
40
+ if (state.movementStarted) {
41
+ return;
42
+ }
43
+
44
+ if (!Number.isFinite(distancePx) || distancePx < REMOTE_HIDE_MOVEMENT_THRESHOLD_PX) {
45
+ return;
46
+ }
47
+
48
+ state.movementStarted = true;
49
+ handler.interactionStart?.(kind);
50
+ }
51
+
52
+ export function handleTouchStart(event, { touchpad, state, handler }) {
53
+ event.preventDefault();
54
+ const touches = event.touches;
55
+
56
+ if (!state.interactionActive && touches.length > 0) {
57
+ state.interactionActive = true;
58
+ }
59
+
60
+ if (touches.length === 1) {
61
+ const t = touches[0];
62
+ const rect = touchpad.getBoundingClientRect();
63
+ const layout = getScrollZoneLayout(rect.width, rect.height, handler.getHandedness?.());
64
+ const localX = t.clientX - rect.left;
65
+ const localY = t.clientY - rect.top;
66
+ const inRightZone =
67
+ localX >= layout.x
68
+ && localX <= layout.x + layout.width
69
+ && localY >= layout.y
70
+ && localY <= layout.y + layout.height;
71
+ state.oneFinger = { x: t.clientX, y: t.clientY };
72
+ state.oneFingerStart = { x: t.clientX, y: t.clientY };
73
+ state.oneFingerMode = inRightZone ? 'scroll' : 'move';
74
+ state.twoFinger = null;
75
+ state.movementStarted = false;
76
+ state.moved = false;
77
+ state.dragEligible = !inRightZone;
78
+ state.touchStartedAt = Date.now();
79
+ state.lastMoveAt = state.touchStartedAt;
80
+ }
81
+
82
+ if (touches.length === 2) {
83
+ stopDrag(state, handler);
84
+ const t1 = touches[0];
85
+ const t2 = touches[1];
86
+ state.twoFinger = {
87
+ p1: { x: t1.clientX, y: t1.clientY },
88
+ p2: { x: t2.clientX, y: t2.clientY },
89
+ };
90
+ state.movementStarted = false;
91
+ state.oneFinger = null;
92
+ state.oneFingerStart = null;
93
+ state.touchStartedAt = Date.now();
94
+ state.moved = false;
95
+ state.dragEligible = false;
96
+ state.lastMoveAt = state.touchStartedAt;
97
+ }
98
+ }
99
+
100
+ export function handleTouchMove(event, { state, handler }) {
101
+ event.preventDefault();
102
+ const touches = event.touches;
103
+
104
+ if (touches.length === 1 && state.oneFinger) {
105
+ const t = touches[0];
106
+ const dx = t.clientX - state.oneFinger.x;
107
+ const dy = t.clientY - state.oneFinger.y;
108
+ const now = Date.now();
109
+ const elapsed = now - state.lastMoveAt;
110
+ const holdDuration = now - state.touchStartedAt;
111
+ const travelFromStart = state.oneFingerStart
112
+ ? distance2D(state.oneFingerStart, { x: t.clientX, y: t.clientY })
113
+ : 0;
114
+
115
+ if (!state.dragActive && travelFromStart > getDragStillDistancePx(handler)) {
116
+ state.dragEligible = false;
117
+ }
118
+
119
+ notifyMovementStartIfNeeded(state, handler, travelFromStart, state.oneFingerMode === 'scroll' ? 'scroll' : 'move');
120
+
121
+ if (state.oneFingerMode === 'scroll') {
122
+ if (Math.abs(dy) > 0.12) {
123
+ state.moved = true;
124
+ handler.scroll(scaleSigned(dy, SCROLL_GAIN));
125
+ }
126
+ } else if (state.dragActive || (state.dragEligible && holdDuration >= getDragHoldMs(handler))) {
127
+ startDrag(state, handler);
128
+ if (Math.abs(dx) + Math.abs(dy) > 0.5) {
129
+ state.moved = true;
130
+ const adjusted = applyNonLinearAcceleration(dx, dy, elapsed);
131
+ handler.move(adjusted.dx, adjusted.dy);
132
+ }
133
+ } else if (Math.abs(dx) + Math.abs(dy) > 0.5) {
134
+ state.moved = true;
135
+ const adjusted = applyNonLinearAcceleration(dx, dy, elapsed);
136
+ handler.move(adjusted.dx, adjusted.dy);
137
+ }
138
+
139
+ state.oneFinger = { x: t.clientX, y: t.clientY };
140
+ state.lastMoveAt = now;
141
+ }
142
+
143
+ if (touches.length === 2 && state.twoFinger) {
144
+ const t1 = { x: touches[0].clientX, y: touches[0].clientY };
145
+ const t2 = { x: touches[1].clientX, y: touches[1].clientY };
146
+ const travelP1 = distance2D(state.twoFinger.p1, t1);
147
+ const travelP2 = distance2D(state.twoFinger.p2, t2);
148
+ const prevMidY = (state.twoFinger.p1.y + state.twoFinger.p2.y) / 2;
149
+ const nextMidY = (t1.y + t2.y) / 2;
150
+ const deltaY = nextMidY - prevMidY;
151
+
152
+ notifyMovementStartIfNeeded(state, handler, Math.max(travelP1, travelP2), 'scroll');
153
+
154
+ if (Math.abs(deltaY) > 0.12) {
155
+ state.moved = true;
156
+ handler.scroll(scaleSigned(deltaY, SCROLL_GAIN));
157
+ }
158
+
159
+ state.twoFinger = { p1: t1, p2: t2 };
160
+ }
161
+ }
162
+
163
+ export function handleTouchEnd(event, { state, handler }) {
164
+ event.preventDefault();
165
+ const duration = Date.now() - state.touchStartedAt;
166
+
167
+ if (event.touches.length === 0) {
168
+ if (state.dragActive) {
169
+ stopDrag(state, handler);
170
+ } else if (!state.moved && duration < 220 && state.oneFingerMode !== 'scroll') {
171
+ if (state.twoFinger) {
172
+ const space = distance2D(state.twoFinger.p1, state.twoFinger.p2);
173
+ if (space > 20) {
174
+ handler.click('right');
175
+ }
176
+ } else {
177
+ handler.click('left');
178
+ }
179
+ }
180
+
181
+ state.oneFinger = null;
182
+ state.oneFingerStart = null;
183
+ state.oneFingerMode = 'move';
184
+ state.twoFinger = null;
185
+ state.movementStarted = false;
186
+ state.moved = false;
187
+ state.dragActive = false;
188
+ state.dragEligible = false;
189
+ state.interactionActive = false;
190
+ handler.flush();
191
+ handler.interactionEnd?.();
192
+ }
193
+ }