diff --git a/src/App.tsx b/src/App.tsx index 4b88f7b4c..c8e70a8c9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -39,7 +39,7 @@ import { engineStreamActor, useSettings, useToken, -} from '@src/machines/appMachine' +} from '@src/lib/singletons' import { commandBarActor } from '@src/machines/commandBarMachine' import { EngineStreamTransition } from '@src/machines/engineStreamMachine' import { onboardingPaths } from '@src/routes/Onboarding/paths' diff --git a/src/Auth.tsx b/src/Auth.tsx index 5ccc6e801..e4df0e622 100644 --- a/src/Auth.tsx +++ b/src/Auth.tsx @@ -1,5 +1,5 @@ import Loading from '@src/components/Loading' -import { useAuthState } from '@src/machines/appMachine' +import { useAuthState } from '@src/lib/singletons' // Wrapper around protected routes, used in src/Router.tsx export const Auth = ({ children }: React.PropsWithChildren) => { diff --git a/src/Router.tsx b/src/Router.tsx index 50b0a5b21..f592783de 100644 --- a/src/Router.tsx +++ b/src/Router.tsx @@ -35,7 +35,7 @@ import { rustContext, } from '@src/lib/singletons' import { reportRejection } from '@src/lib/trap' -import { useToken } from '@src/machines/appMachine' +import { useToken } from '@src/lib/singletons' import RootLayout from '@src/Root' import Home from '@src/routes/Home' import Onboarding, { onboardingRoutes } from '@src/routes/Onboarding' diff --git a/src/clientSideScene/ClientSideSceneComp.tsx b/src/clientSideScene/ClientSideSceneComp.tsx index 58a36be52..b9b0d7754 100644 --- a/src/clientSideScene/ClientSideSceneComp.tsx +++ b/src/clientSideScene/ClientSideSceneComp.tsx @@ -40,7 +40,7 @@ import { } from '@src/lib/singletons' import { err, reportRejection, trap } from '@src/lib/trap' import { throttle, toSync } from '@src/lib/utils' -import type { useSettings } from '@src/machines/appMachine' +import type { useSettings } from '@src/lib/singletons' import { commandBarActor } from '@src/machines/commandBarMachine' import type { SegmentOverlay } from '@src/machines/modelingMachine' diff --git a/src/components/AppHeader.tsx b/src/components/AppHeader.tsx index 81f537648..3e4dd5e6a 100644 --- a/src/components/AppHeader.tsx +++ b/src/components/AppHeader.tsx @@ -5,7 +5,7 @@ import { RefreshButton } from '@src/components/RefreshButton' import UserSidebarMenu from '@src/components/UserSidebarMenu' import { isDesktop } from '@src/lib/isDesktop' import { type IndexLoaderData } from '@src/lib/types' -import { useUser } from '@src/machines/appMachine' +import { useUser } from '@src/lib/singletons' import styles from './AppHeader.module.css' diff --git a/src/components/CameraProjectionToggle.tsx b/src/components/CameraProjectionToggle.tsx index 314fc56f5..aa0c3f7b3 100644 --- a/src/components/CameraProjectionToggle.tsx +++ b/src/components/CameraProjectionToggle.tsx @@ -1,7 +1,7 @@ import { Switch } from '@headlessui/react' import { useEffect, useState } from 'react' -import { settingsActor, useSettings } from '@src/machines/appMachine' +import { settingsActor, useSettings } from '@src/lib/singletons' export function CameraProjectionToggle() { const settings = useSettings() diff --git a/src/components/CommandBar/CommandBarKclInput.tsx b/src/components/CommandBar/CommandBarKclInput.tsx index 68204a2a7..7591ca728 100644 --- a/src/components/CommandBar/CommandBarKclInput.tsx +++ b/src/components/CommandBar/CommandBarKclInput.tsx @@ -29,7 +29,7 @@ import { err } from '@src/lib/trap' import { useCalculateKclExpression } from '@src/lib/useCalculateKclExpression' import { roundOff } from '@src/lib/utils' import { varMentions } from '@src/lib/varCompletionExtension' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' import { commandBarActor, useCommandBarState, diff --git a/src/components/DownloadAppBanner.tsx b/src/components/DownloadAppBanner.tsx index ee955a4fa..0081e1b75 100644 --- a/src/components/DownloadAppBanner.tsx +++ b/src/components/DownloadAppBanner.tsx @@ -3,7 +3,7 @@ import { useState } from 'react' import { ActionButton } from '@src/components/ActionButton' import { CREATE_FILE_URL_PARAM } from '@src/lib/constants' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' import { useSearchParams } from 'react-router-dom' const DownloadAppBanner = () => { diff --git a/src/components/EngineStream.tsx b/src/components/EngineStream.tsx index 842b8b7bb..8fe3369ee 100644 --- a/src/components/EngineStream.tsx +++ b/src/components/EngineStream.tsx @@ -18,7 +18,7 @@ import { REASONABLE_TIME_TO_REFRESH_STREAM_SIZE } from '@src/lib/timings' import { err, reportRejection, trap } from '@src/lib/trap' import type { IndexLoaderData } from '@src/lib/types' import { uuidv4 } from '@src/lib/utils' -import { engineStreamActor, useSettings } from '@src/machines/appMachine' +import { engineStreamActor, useSettings } from '@src/lib/singletons' import { useCommandBarState } from '@src/machines/commandBarMachine' import { EngineStreamState, diff --git a/src/components/FileMachineProvider.tsx b/src/components/FileMachineProvider.tsx index 4f596a59f..0aa19fde5 100644 --- a/src/components/FileMachineProvider.tsx +++ b/src/components/FileMachineProvider.tsx @@ -33,7 +33,7 @@ import { markOnce } from '@src/lib/performance' import { codeManager, kclManager } from '@src/lib/singletons' import { err, reportRejection } from '@src/lib/trap' import { type IndexLoaderData } from '@src/lib/types' -import { useSettings, useToken } from '@src/machines/appMachine' +import { useSettings, useToken } from '@src/lib/singletons' import { commandBarActor } from '@src/machines/commandBarMachine' import { fileMachine } from '@src/machines/fileMachine' import { modelingMenuCallbackMostActions } from '@src/menu/register' diff --git a/src/components/Gizmo.tsx b/src/components/Gizmo.tsx index b05dddd88..fadd0d14e 100644 --- a/src/components/Gizmo.tsx +++ b/src/components/Gizmo.tsx @@ -27,7 +27,7 @@ import { useModelingContext } from '@src/hooks/useModelingContext' import { AxisNames } from '@src/lib/constants' import { sceneInfra } from '@src/lib/singletons' import { reportRejection } from '@src/lib/trap' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' const CANVAS_SIZE = 80 const FRUSTUM_SIZE = 0.5 diff --git a/src/components/HelpMenu.tsx b/src/components/HelpMenu.tsx index 64c83063d..7274658a4 100644 --- a/src/components/HelpMenu.tsx +++ b/src/components/HelpMenu.tsx @@ -10,7 +10,7 @@ import { createAndOpenNewTutorialProject } from '@src/lib/desktopFS' import { openExternalBrowserIfDesktop } from '@src/lib/openWindow' import { PATHS } from '@src/lib/paths' import { reportRejection } from '@src/lib/trap' -import { settingsActor } from '@src/machines/appMachine' +import { settingsActor } from '@src/lib/singletons' import type { WebContentSendPayload } from '@src/menu/channels' const HelpMenuDivider = () => ( diff --git a/src/components/LspProvider.tsx b/src/components/LspProvider.tsx index 8fd358065..5e9155bec 100644 --- a/src/components/LspProvider.tsx +++ b/src/components/LspProvider.tsx @@ -27,7 +27,7 @@ import { PATHS } from '@src/lib/paths' import type { FileEntry } from '@src/lib/project' import { codeManager } from '@src/lib/singletons' import { err } from '@src/lib/trap' -import { useToken } from '@src/machines/appMachine' +import { useToken } from '@src/lib/singletons' function getWorkspaceFolders(): LSP.WorkspaceFolder[] { return [] diff --git a/src/components/ModelStateIndicator.tsx b/src/components/ModelStateIndicator.tsx index cdaef3276..f27d662d5 100644 --- a/src/components/ModelStateIndicator.tsx +++ b/src/components/ModelStateIndicator.tsx @@ -1,4 +1,4 @@ -import { engineStreamActor } from '@src/machines/appMachine' +import { engineStreamActor } from '@src/lib/singletons' import { EngineStreamState } from '@src/machines/engineStreamMachine' import { useSelector } from '@xstate/react' diff --git a/src/components/ModelingMachineProvider.tsx b/src/components/ModelingMachineProvider.tsx index 82ebe6b6b..54822d54c 100644 --- a/src/components/ModelingMachineProvider.tsx +++ b/src/components/ModelingMachineProvider.tsx @@ -110,7 +110,7 @@ import { submitAndAwaitTextToKcl } from '@src/lib/textToCad' import { err, reject, reportRejection, trap } from '@src/lib/trap' import type { IndexLoaderData } from '@src/lib/types' import { platform, uuidv4 } from '@src/lib/utils' -import { useSettings, useToken } from '@src/machines/appMachine' +import { useSettings, useToken } from '@src/lib/singletons' import { commandBarActor } from '@src/machines/commandBarMachine' import { kclEditorActor } from '@src/machines/kclEditorMachine' import { diff --git a/src/components/ModelingSidebar/ModelingPane.tsx b/src/components/ModelingSidebar/ModelingPane.tsx index 734b8dbd6..b919b8ff0 100644 --- a/src/components/ModelingSidebar/ModelingPane.tsx +++ b/src/components/ModelingSidebar/ModelingPane.tsx @@ -5,7 +5,7 @@ import { ActionButton } from '@src/components/ActionButton' import { ActionIcon } from '@src/components/ActionIcon' import type { CustomIconName } from '@src/components/CustomIcon' import Tooltip from '@src/components/Tooltip' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' import { onboardingPaths } from '@src/routes/Onboarding/paths' import styles from './ModelingPane.module.css' diff --git a/src/components/ModelingSidebar/ModelingPanes/KclEditorPane.tsx b/src/components/ModelingSidebar/ModelingPanes/KclEditorPane.tsx index 79daaef53..66d847d7a 100644 --- a/src/components/ModelingSidebar/ModelingPanes/KclEditorPane.tsx +++ b/src/components/ModelingSidebar/ModelingPanes/KclEditorPane.tsx @@ -47,7 +47,7 @@ import { codeManagerHistoryCompartment } from '@src/lang/codeManager' import { codeManager, editorManager, kclManager } from '@src/lib/singletons' import { Themes, getSystemTheme } from '@src/lib/theme' import { onMouseDragMakeANewNumber, onMouseDragRegex } from '@src/lib/utils' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' import { editorIsMountedSelector, kclEditorActor, diff --git a/src/components/ModelingSidebar/ModelingSidebar.tsx b/src/components/ModelingSidebar/ModelingSidebar.tsx index ab9761e16..ebfc66357 100644 --- a/src/components/ModelingSidebar/ModelingSidebar.tsx +++ b/src/components/ModelingSidebar/ModelingSidebar.tsx @@ -22,7 +22,7 @@ import { useKclContext } from '@src/lang/KclProvider' import { EngineConnectionStateType } from '@src/lang/std/engineConnection' import { SIDEBAR_BUTTON_SUFFIX } from '@src/lib/constants' import { isDesktop } from '@src/lib/isDesktop' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' import { commandBarActor } from '@src/machines/commandBarMachine' import { onboardingPaths } from '@src/routes/Onboarding/paths' diff --git a/src/components/ProjectSidebarMenu.tsx b/src/components/ProjectSidebarMenu.tsx index 37af452bd..eea709719 100644 --- a/src/components/ProjectSidebarMenu.tsx +++ b/src/components/ProjectSidebarMenu.tsx @@ -23,7 +23,7 @@ import { kclManager, } from '@src/lib/singletons' import { type IndexLoaderData } from '@src/lib/types' -import { useToken } from '@src/machines/appMachine' +import { useToken } from '@src/lib/singletons' import { commandBarActor } from '@src/machines/commandBarMachine' const ProjectSidebarMenu = ({ diff --git a/src/components/ProjectsContextProvider.tsx b/src/components/ProjectsContextProvider.tsx index 1766f54ff..21f43112b 100644 --- a/src/components/ProjectsContextProvider.tsx +++ b/src/components/ProjectsContextProvider.tsx @@ -33,7 +33,7 @@ import { PATHS } from '@src/lib/paths' import type { Project } from '@src/lib/project' import { codeManager, kclManager } from '@src/lib/singletons' import { err } from '@src/lib/trap' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' import { commandBarActor } from '@src/machines/commandBarMachine' import { projectsMachine } from '@src/machines/projectsMachine' diff --git a/src/components/Providers/SystemIOProviderDesktop.tsx b/src/components/Providers/SystemIOProviderDesktop.tsx index f2333a113..15bf56d8d 100644 --- a/src/components/Providers/SystemIOProviderDesktop.tsx +++ b/src/components/Providers/SystemIOProviderDesktop.tsx @@ -1,6 +1,6 @@ import { useFileSystemWatcher } from '@src/hooks/useFileSystemWatcher' import { PATHS } from '@src/lib/paths' -import { systemIOActor, useSettings } from '@src/machines/appMachine' +import { systemIOActor, useSettings } from '@src/lib/singletons' import { useHasListedProjects, useProjectDirectoryPath, diff --git a/src/components/RefreshButton.tsx b/src/components/RefreshButton.tsx index 12fe4bb8e..3def91cda 100644 --- a/src/components/RefreshButton.tsx +++ b/src/components/RefreshButton.tsx @@ -13,7 +13,7 @@ import { } from '@src/lib/singletons' import { reportRejection } from '@src/lib/trap' import { toSync } from '@src/lib/utils' -import { useToken } from '@src/machines/appMachine' +import { useToken } from '@src/lib/singletons' import type { WebContentSendPayload } from '@src/menu/channels' export const RefreshButton = ({ children }: React.PropsWithChildren) => { diff --git a/src/components/RouteProvider.tsx b/src/components/RouteProvider.tsx index c118d20f5..b18f55743 100644 --- a/src/components/RouteProvider.tsx +++ b/src/components/RouteProvider.tsx @@ -18,7 +18,7 @@ import { markOnce } from '@src/lib/performance' import { loadAndValidateSettings } from '@src/lib/settings/settingsUtils' import { trap } from '@src/lib/trap' import type { IndexLoaderData } from '@src/lib/types' -import { settingsActor, useSettings } from '@src/machines/appMachine' +import { settingsActor, useSettings } from '@src/lib/singletons' export const RouteProviderContext = createContext({}) diff --git a/src/components/Settings/AllSettingsFields.tsx b/src/components/Settings/AllSettingsFields.tsx index 7eda78850..9e50f2e8e 100644 --- a/src/components/Settings/AllSettingsFields.tsx +++ b/src/components/Settings/AllSettingsFields.tsx @@ -28,7 +28,7 @@ import { } from '@src/lib/settings/settingsUtils' import { reportRejection } from '@src/lib/trap' import { toSync } from '@src/lib/utils' -import { settingsActor, useSettings } from '@src/machines/appMachine' +import { settingsActor, useSettings } from '@src/lib/singletons' import { APP_VERSION, IS_NIGHTLY, getReleaseUrl } from '@src/routes/utils' import { waitFor } from 'xstate' diff --git a/src/components/Settings/SettingsFieldInput.tsx b/src/components/Settings/SettingsFieldInput.tsx index a5a45bfa3..545c0279c 100644 --- a/src/components/Settings/SettingsFieldInput.tsx +++ b/src/components/Settings/SettingsFieldInput.tsx @@ -9,7 +9,7 @@ import type { WildcardSetEvent, } from '@src/lib/settings/settingsTypes' import { getSettingInputType } from '@src/lib/settings/settingsUtils' -import { settingsActor, useSettings } from '@src/machines/appMachine' +import { settingsActor, useSettings } from '@src/lib/singletons' interface SettingsFieldInputProps { // We don't need the fancy types here, diff --git a/src/components/Settings/SettingsSearchBar.tsx b/src/components/Settings/SettingsSearchBar.tsx index b36429fb3..40e48190f 100644 --- a/src/components/Settings/SettingsSearchBar.tsx +++ b/src/components/Settings/SettingsSearchBar.tsx @@ -8,7 +8,7 @@ import { useNavigate } from 'react-router-dom' import { CustomIcon } from '@src/components/CustomIcon' import { interactionMap } from '@src/lib/settings/initialKeybindings' import type { SettingsLevel } from '@src/lib/settings/settingsTypes' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' type ExtendedSettingsLevel = SettingsLevel | 'keybindings' diff --git a/src/components/Settings/SettingsSectionsList.tsx b/src/components/Settings/SettingsSectionsList.tsx index f1fbfcfd5..e3dea57a5 100644 --- a/src/components/Settings/SettingsSectionsList.tsx +++ b/src/components/Settings/SettingsSectionsList.tsx @@ -3,7 +3,7 @@ import decamelize from 'decamelize' import type { Setting } from '@src/lib/settings/initialSettings' import type { SettingsLevel } from '@src/lib/settings/settingsTypes' import { shouldHideSetting } from '@src/lib/settings/settingsUtils' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' interface SettingsSectionsListProps { searchParamTab: SettingsLevel diff --git a/src/components/UserSidebarMenu.tsx b/src/components/UserSidebarMenu.tsx index 685bf21f7..813bc0320 100644 --- a/src/components/UserSidebarMenu.tsx +++ b/src/components/UserSidebarMenu.tsx @@ -11,7 +11,7 @@ import { useAbsoluteFilePath } from '@src/hooks/useAbsoluteFilePath' import usePlatform from '@src/hooks/usePlatform' import { isDesktop } from '@src/lib/isDesktop' import { PATHS } from '@src/lib/paths' -import { authActor } from '@src/machines/appMachine' +import { authActor } from '@src/lib/singletons' type User = Models['User_type'] diff --git a/src/components/ViewControlMenu.tsx b/src/components/ViewControlMenu.tsx index 123131beb..e8c3ce88b 100644 --- a/src/components/ViewControlMenu.tsx +++ b/src/components/ViewControlMenu.tsx @@ -12,7 +12,7 @@ import type { AxisNames } from '@src/lib/constants' import { VIEW_NAMES_SEMANTIC } from '@src/lib/constants' import { sceneInfra } from '@src/lib/singletons' import { reportRejection } from '@src/lib/trap' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' export function useViewControlMenuItems() { const { state: modelingState, send: modelingSend } = useModelingContext() diff --git a/src/hooks/useAuthNavigation.tsx b/src/hooks/useAuthNavigation.tsx index 116f8e1d8..63a3d7eab 100644 --- a/src/hooks/useAuthNavigation.tsx +++ b/src/hooks/useAuthNavigation.tsx @@ -2,7 +2,7 @@ import { useEffect } from 'react' import { useLocation, useNavigate } from 'react-router-dom' import { PATHS } from '@src/lib/paths' -import { useAuthState } from '@src/machines/appMachine' +import { useAuthState } from '@src/lib/singletons' /** * A simple hook that listens to the auth state of the app and navigates diff --git a/src/hooks/useCreateFileLinkQueryWatcher.ts b/src/hooks/useCreateFileLinkQueryWatcher.ts index d7e812f1b..805ba474e 100644 --- a/src/hooks/useCreateFileLinkQueryWatcher.ts +++ b/src/hooks/useCreateFileLinkQueryWatcher.ts @@ -9,7 +9,7 @@ import { CREATE_FILE_URL_PARAM, DEFAULT_FILE_NAME } from '@src/lib/constants' import { isDesktop } from '@src/lib/isDesktop' import type { FileLinkParams } from '@src/lib/links' import { PATHS } from '@src/lib/paths' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' // For initializing the command arguments, we actually want `method` to be undefined // so that we don't skip it in the command palette. diff --git a/src/hooks/useEngineConnectionSubscriptions.ts b/src/hooks/useEngineConnectionSubscriptions.ts index e0137c58a..860e5047e 100644 --- a/src/hooks/useEngineConnectionSubscriptions.ts +++ b/src/hooks/useEngineConnectionSubscriptions.ts @@ -27,7 +27,7 @@ import { } from '@src/lib/singletons' import { err, reportRejection } from '@src/lib/trap' import { getModuleId } from '@src/lib/utils' -import { engineStreamActor } from '@src/machines/appMachine' +import { engineStreamActor } from '@src/lib/singletons' import { EngineStreamState } from '@src/machines/engineStreamMachine' import type { EdgeCutInfo, diff --git a/src/hooks/useResolvedTheme.ts b/src/hooks/useResolvedTheme.ts index 4f13c94cc..8778071d0 100644 --- a/src/hooks/useResolvedTheme.ts +++ b/src/hooks/useResolvedTheme.ts @@ -1,5 +1,5 @@ import { Themes, getSystemTheme } from '@src/lib/theme' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' /** * Resolves the current theme based on the theme setting diff --git a/src/index.tsx b/src/index.tsx index 59d23eac4..1ae0620a2 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -13,7 +13,7 @@ import { initializeWindowExceptionHandler } from '@src/lib/exceptions' import { isDesktop } from '@src/lib/isDesktop' import { markOnce } from '@src/lib/performance' import { reportRejection } from '@src/lib/trap' -import { appActor } from '@src/machines/appMachine' +import { appActor } from '@src/lib/singletons' import reportWebVitals from '@src/reportWebVitals' markOnce('code/willAuth') diff --git a/src/lib/commandBarConfigs/authCommandConfig.ts b/src/lib/commandBarConfigs/authCommandConfig.ts index 0417d973d..efee5a380 100644 --- a/src/lib/commandBarConfigs/authCommandConfig.ts +++ b/src/lib/commandBarConfigs/authCommandConfig.ts @@ -1,5 +1,5 @@ import type { Command } from '@src/lib/commandTypes' -import { authActor } from '@src/machines/appMachine' +import { authActor } from '@src/lib/singletons' import { ACTOR_IDS } from '@src/machines/machineConstants' export const authCommands: Command[] = [ diff --git a/src/lib/commandBarConfigs/namedViewsConfig.ts b/src/lib/commandBarConfigs/namedViewsConfig.ts index 997e3cd16..0c21af1c4 100644 --- a/src/lib/commandBarConfigs/namedViewsConfig.ts +++ b/src/lib/commandBarConfigs/namedViewsConfig.ts @@ -12,7 +12,7 @@ import type { Command, CommandArgumentOption } from '@src/lib/commandTypes' import { engineCommandManager } from '@src/lib/singletons' import { err, reportRejection } from '@src/lib/trap' import { uuidv4 } from '@src/lib/utils' -import { getSettings, settingsActor } from '@src/machines/appMachine' +import { getSettings, settingsActor } from '@src/lib/singletons' function isWorldCoordinateSystemType( x: string diff --git a/src/lib/commandBarConfigs/projectsCommandConfig.ts b/src/lib/commandBarConfigs/projectsCommandConfig.ts index ccab2d989..7465c6ea5 100644 --- a/src/lib/commandBarConfigs/projectsCommandConfig.ts +++ b/src/lib/commandBarConfigs/projectsCommandConfig.ts @@ -176,7 +176,7 @@ import { folderSnapshot, defaultProjectFolderNameSnapshot, } from '@src/machines/systemIO/snapshotContext' -import { systemIOActor } from '@src/machines/appMachine' +import { systemIOActor } from '@src/lib/singletons' import { SystemIOMachineEvents } from '@src/machines/systemIO/utils' export const openProjectCommand: Command = { diff --git a/src/lib/routeLoaders.ts b/src/lib/routeLoaders.ts index 8d547e366..de46b4c4a 100644 --- a/src/lib/routeLoaders.ts +++ b/src/lib/routeLoaders.ts @@ -20,7 +20,7 @@ import type { HomeLoaderData, IndexLoaderData, } from '@src/lib/types' -import { settingsActor } from '@src/machines/appMachine' +import { settingsActor } from '@src/lib/singletons' export const telemetryLoader: LoaderFunction = async ({ params, diff --git a/src/lib/selections.ts b/src/lib/selections.ts index 428df0f5e..2de46904d 100644 --- a/src/lib/selections.ts +++ b/src/lib/selections.ts @@ -43,7 +43,7 @@ import { isOverlap, uuidv4, } from '@src/lib/utils' -import { engineStreamActor } from '@src/machines/appMachine' +import { engineStreamActor } from '@src/lib/singletons' import type { ModelingMachineEvent } from '@src/machines/modelingMachine' import { showUnsupportedSelectionToast } from '@src/components/ToastUnsupportedSelection' diff --git a/src/lib/settings/settingsUtils.ts b/src/lib/settings/settingsUtils.ts index 72306eb6b..f76a8c674 100644 --- a/src/lib/settings/settingsUtils.ts +++ b/src/lib/settings/settingsUtils.ts @@ -456,7 +456,7 @@ export function getSettingInputType(setting: Setting) { export const jsAppSettings = async () => { let jsAppSettings = default_app_settings() if (!TEST) { - const settings = await import('@src/machines/appMachine').then((module) => + const settings = await import('@src/lib/singletons').then((module) => module.getSettings() ) if (settings) { diff --git a/src/lib/singletons.ts b/src/lib/singletons.ts index 7ff9134d0..202e14ccd 100644 --- a/src/lib/singletons.ts +++ b/src/lib/singletons.ts @@ -74,7 +74,7 @@ if (typeof window !== 'undefined') { ;(window as any).enableMousePositionLogs = () => document.addEventListener('mousemove', (e) => console.log(`await page.mouse.click(${e.clientX}, ${e.clientY})`) - ) + ) ;(window as any).enableFillet = () => { ;(window as any)._enableFillet = true } @@ -90,3 +90,109 @@ if (typeof window !== 'undefined') { }, }) } + + +import { useSelector } from '@xstate/react' +import { createActor, setup, spawnChild } from 'xstate' + +import { isDesktop } from '@src/lib/isDesktop' +import { createSettings } from '@src/lib/settings/initialSettings' +import { authMachine } from '@src/machines/authMachine' +import type { EngineStreamActor } from '@src/machines/engineStreamMachine' +import { + engineStreamContextCreate, + engineStreamMachine, +} from '@src/machines/engineStreamMachine' +import { ACTOR_IDS } from '@src/machines/machineConstants' +import { settingsMachine } from '@src/machines/settingsMachine' +import { systemIOMachineDesktop } from '@src/machines/systemIO/systemIOMachineDesktop' +import { systemIOMachineWeb } from '@src/machines/systemIO/systemIOMachineWeb' +const { AUTH, SETTINGS, SYSTEM_IO, ENGINE_STREAM } = ACTOR_IDS +const appMachineActors = { + [AUTH]: authMachine, + [SETTINGS]: settingsMachine, + [SYSTEM_IO]: isDesktop() ? systemIOMachineDesktop : systemIOMachineWeb, + [ENGINE_STREAM]: engineStreamMachine, +} as const + +const appMachine = setup({ + types: {} as { + children: { + auth: typeof AUTH + settings: typeof SETTINGS + systemIO: typeof SYSTEM_IO + } + }, + actors: appMachineActors, + context: {} as { + codeManager: any, + kclManager: any, + engineCommandManager: any, + sceneInfra: any, + sceneEntitiesManager: any + } +}).createMachine({ + id: 'modeling-app', + context:{ + codeManager: codeManager, + kclManager: kclManager, + engineCommandManager: engineCommandManager, + sceneInfra: sceneInfra, + sceneEntitiesManager: sceneEntitiesManager + }, + entry: [ + spawnChild(AUTH, { id: AUTH, systemId: AUTH }), + spawnChild(SETTINGS, { + id: SETTINGS, + systemId: SETTINGS, + input: createSettings(), + }), + spawnChild(SYSTEM_IO, { id: SYSTEM_IO, systemId: SYSTEM_IO }), + spawnChild(ENGINE_STREAM, { + id: ENGINE_STREAM, + systemId: ENGINE_STREAM, + input: engineStreamContextCreate(), + }), + ], +}) + +export const appActor = createActor(appMachine, { + systemId: 'root', +}) + +/** + * GOTCHA: the type coercion of this actor works because it is spawned for + * the lifetime of {appActor}, but would not work if it were invoked + * or if it were destroyed under any conditions during {appActor}'s life + */ +export const authActor = appActor.getSnapshot().children.auth! +export const useAuthState = () => useSelector(authActor, (state) => state) +export const useToken = () => + useSelector(authActor, (state) => state.context.token) +export const useUser = () => + useSelector(authActor, (state) => state.context.user) + +/** + * GOTCHA: the type coercion of this actor works because it is spawned for + * the lifetime of {appActor}, but would not work if it were invoked + * or if it were destroyed under any conditions during {appActor}'s life + */ +export const settingsActor = appActor.getSnapshot().children.settings! +export const getSettings = () => { + const { currentProject: _, ...settings } = settingsActor.getSnapshot().context + return settings +} +export const useSettings = () => + useSelector(settingsActor, (state) => { + // We have to peel everything that isn't settings off + const { currentProject, ...settings } = state.context + return settings + }) + +export const systemIOActor = appActor.getSnapshot().children.systemIO! + +export const engineStreamActor = appActor.system.get( + ENGINE_STREAM +) as EngineStreamActor + +window.actor = systemIOActor diff --git a/src/machines/engineStreamMachine.ts b/src/machines/engineStreamMachine.ts index 04b656bee..1c94af62f 100644 --- a/src/machines/engineStreamMachine.ts +++ b/src/machines/engineStreamMachine.ts @@ -1,4 +1,3 @@ -import { engineCommandManager, sceneInfra } from '@src/lib/singletons' import type { MutableRefObject } from 'react' import type { ActorRefFrom } from 'xstate' import { assign, fromPromise, setup } from 'xstate' @@ -79,7 +78,7 @@ export const engineStreamMachine = setup({ actors: { [EngineStreamTransition.Play]: fromPromise( async ({ - input: { context, params }, + input: { context, params, rootContext}, }: { input: { context: EngineStreamContext; params: { zoomToFit: boolean } } }) => { @@ -98,7 +97,7 @@ export const engineStreamMachine = setup({ return } - await sceneInfra.camControls.restoreRemoteCameraStateAndTriggerSync() + await rootContext.sceneInfra.camControls.restoreRemoteCameraStateAndTriggerSync() video.style.display = 'block' canvas.style.display = 'none' @@ -108,7 +107,7 @@ export const engineStreamMachine = setup({ ), [EngineStreamTransition.Pause]: fromPromise( async ({ - input: { context }, + input: { context, rootContext }, }: { input: { context: EngineStreamContext } }) => { @@ -123,7 +122,7 @@ export const engineStreamMachine = setup({ await holdOntoVideoFrameInCanvas(video, canvas) video.style.display = 'none' - await sceneInfra.camControls.saveRemoteCameraState() + await rootContext.sceneInfra.camControls.saveRemoteCameraState() // Make sure we're on the next frame for no flickering between canvas // and the video elements. @@ -138,17 +137,18 @@ export const engineStreamMachine = setup({ context.mediaStream = null video.srcObject = null - engineCommandManager.tearDown({ idleMode: true }) + rootContext.engineCommandManager.tearDown({ idleMode: true }) })() ) } ), [EngineStreamTransition.StartOrReconfigureEngine]: fromPromise( async ({ - input: { context, event }, + input: { context, event, rootContext }, }: { input: { context: EngineStreamContext; event: any } }) => { + console.log(context,event, rootContext) if (!context.authToken) return const video = context.videoRef.current @@ -172,10 +172,10 @@ export const engineStreamMachine = setup({ ...event.settings, } - engineCommandManager.settings = settingsNext + rootContext.engineCommandManager.settings = settingsNext window.requestAnimationFrame(() => { - engineCommandManager.start({ + rootContext.engineCommandManager.start({ setMediaStream: event.onMediaStream, setIsStreamReady: (isStreamReady: boolean) => { event.setAppState({ isStreamReady }) @@ -225,7 +225,12 @@ export const engineStreamMachine = setup({ reenter: true, invoke: { src: EngineStreamTransition.StartOrReconfigureEngine, - input: (args) => args, + input: (args) => ({ + context: args.context, + rootContext: args.self.system.get('root').getSnapshot().context, + params: { zoomToFit: args.context.zoomToFit }, + event: args.event + }), }, on: { // Transition requested by engineConnection @@ -246,6 +251,7 @@ export const engineStreamMachine = setup({ src: EngineStreamTransition.Play, input: (args) => ({ context: args.context, + rootContext: args.self.system.get('root').getSnapshot().context, params: { zoomToFit: args.context.zoomToFit }, }), }, @@ -261,7 +267,11 @@ export const engineStreamMachine = setup({ [EngineStreamState.Reconfiguring]: { invoke: { src: EngineStreamTransition.StartOrReconfigureEngine, - input: (args) => args, + input: (args) => ({ + context: args.context, + rootContext: args.self.system.get('root').getSnapshot().context, + event: args.event + }), onDone: { target: EngineStreamState.Playing, }, @@ -270,7 +280,10 @@ export const engineStreamMachine = setup({ [EngineStreamState.Paused]: { invoke: { src: EngineStreamTransition.Pause, - input: (args) => args, + input: (args) => ({ + context: args.context, + rootContext: args.self.system.get('root').getSnapshot().context, + }), }, on: { [EngineStreamTransition.StartOrReconfigureEngine]: { @@ -282,7 +295,11 @@ export const engineStreamMachine = setup({ reenter: true, invoke: { src: EngineStreamTransition.StartOrReconfigureEngine, - input: (args) => args, + input: (args) => ({ + context: args.context, + rootContext: args.self.system.get('root').getSnapshot().context, + event: args.event + }), }, on: { // The stream can be paused as it's resuming. diff --git a/src/machines/settingsMachine.ts b/src/machines/settingsMachine.ts index b51e96c71..8590add96 100644 --- a/src/machines/settingsMachine.ts +++ b/src/machines/settingsMachine.ts @@ -35,13 +35,6 @@ import { saveSettings, setSettingsAtLevel, } from '@src/lib/settings/settingsUtils' -import { - codeManager, - engineCommandManager, - kclManager, - sceneEntitiesManager, - sceneInfra, -} from '@src/lib/singletons' import { Themes, darkModeMatcher, @@ -95,13 +88,14 @@ export const settingsMachine = setup({ doNotPersist: boolean context: SettingsMachineContext toastCallback?: () => void + rootContext: any } >(async ({ input }) => { // Without this, when a user changes the file, it'd // create a detection loop with the file-system watcher. if (input.doNotPersist) return - codeManager.writeCausedByAppCheckedInFileTreeFileSystemWatcher = true + input.rootContext.codeManager.writeCausedByAppCheckedInFileTreeFileSystemWatcher = true const { currentProject, ...settings } = input.context const val = await saveSettings(settings, currentProject?.path) @@ -190,20 +184,28 @@ export const settingsMachine = setup({ }), }, actions: { - setEngineTheme: ({ context }) => { + setEngineTheme: ({ context, self }) => { + const rootContext = self.system.get('root').getSnapshot().context + const engineCommandManager = rootContext.engineCommandManager if (engineCommandManager && context.app.theme.current) { engineCommandManager .setTheme(context.app.theme.current) .catch(reportRejection) } }, - setClientTheme: ({ context }) => { + setClientTheme: ({ context, self }) => { + const rootContext = self.system.get('root').getSnapshot().context + const sceneInfra = rootContext.sceneInfra + const sceneEntitiesManager = rootContext.sceneEntitiesManager + if (!sceneInfra || !sceneEntitiesManager) return const opposingTheme = getOppositeTheme(context.app.theme.current) sceneInfra.theme = opposingTheme sceneEntitiesManager.updateSegmentBaseColor(opposingTheme) }, - setAllowOrbitInSketchMode: ({ context }) => { + setAllowOrbitInSketchMode: ({ context, self }) => { + const rootContext = self.system.get('root').getSnapshot().context + const sceneInfra = rootContext.sceneInfra if (!sceneInfra.camControls) return sceneInfra.camControls._setting_allowOrbitInSketchMode = context.app.allowOrbitInSketchMode.current @@ -232,7 +234,9 @@ export const settingsMachine = setup({ id: `${event.type}.success`, }) }, - 'Execute AST': ({ context, event }) => { + 'Execute AST': ({ context, event, self }) => { + const rootContext = self.system.get('root').getSnapshot().context + const kclManager = rootContext.kclManager try { const relevantSetting = (s: typeof settings) => { return ( @@ -345,8 +349,10 @@ export const settingsMachine = setup({ currentTheme === Themes.System ? getSystemTheme() : currentTheme ) }, - setEngineCameraProjection: ({ context }) => { + setEngineCameraProjection: ({ context, self }) => { const newCurrentProjection = context.modeling.cameraProjection.current + const rootContext = self.system.get('root').getSnapshot().context + const sceneInfra = rootContext.sceneInfra sceneInfra.camControls.setEngineCameraProjection(newCurrentProjection) }, sendThemeToWatcher: sendTo('watchSystemTheme', ({ context }) => ({ @@ -532,7 +538,7 @@ export const settingsMachine = setup({ console.error('Error persisting settings') }, }, - input: ({ context, event }) => { + input: ({ context, event, self }) => { if ( event.type === 'set.app.namedViews' && 'toastCallback' in event.data @@ -547,6 +553,7 @@ export const settingsMachine = setup({ return { doNotPersist: event.doNotPersist ?? false, context, + rootContext: self.system.get('root').getSnapshot().context, } }, }, diff --git a/src/machines/systemIO/hooks.ts b/src/machines/systemIO/hooks.ts index f7a58e14c..b5917de4c 100644 --- a/src/machines/systemIO/hooks.ts +++ b/src/machines/systemIO/hooks.ts @@ -1,4 +1,4 @@ -import { systemIOActor } from '@src/machines/appMachine' +import { systemIOActor } from '@src/lib/singletons' import { useSelector } from '@xstate/react' export const useRequestedProjectName = () => useSelector(systemIOActor, (state) => state.context.requestedProjectName) diff --git a/src/machines/systemIO/snapshotContext.ts b/src/machines/systemIO/snapshotContext.ts index fddf28ae8..b227bed92 100644 --- a/src/machines/systemIO/snapshotContext.ts +++ b/src/machines/systemIO/snapshotContext.ts @@ -1,4 +1,4 @@ -import { systemIOActor } from '@src/machines/appMachine' +import { systemIOActor } from '@src/lib/singletons' export const folderSnapshot = () => { const { folders } = systemIOActor.getSnapshot().context diff --git a/src/machines/systemIO/systemIOMachine.ts b/src/machines/systemIO/systemIOMachine.ts index 349795ec9..99122a9ca 100644 --- a/src/machines/systemIO/systemIOMachine.ts +++ b/src/machines/systemIO/systemIOMachine.ts @@ -190,6 +190,7 @@ export const systemIOMachine = setup({ requestedProjectName: string requestedFileName: string requestedCode: string + rootContext: any } }): Promise<{ message: string @@ -361,13 +362,14 @@ export const systemIOMachine = setup({ invoke: { id: SystemIOMachineActors.createKCLFile, src: SystemIOMachineActors.createKCLFile, - input: ({ context, event }) => { + input: ({ context, event, self}) => { assertEvent(event, SystemIOMachineEvents.createKCLFile) return { context, requestedProjectName: event.data.requestedProjectName, requestedFileName: event.data.requestedFileName, requestedCode: event.data.requestedCode, + rootContext: self.system.get('root').getSnapshot().context } }, onDone: { diff --git a/src/machines/systemIO/systemIOMachineWeb.ts b/src/machines/systemIO/systemIOMachineWeb.ts index b61f7b179..01f0c4eec 100644 --- a/src/machines/systemIO/systemIOMachineWeb.ts +++ b/src/machines/systemIO/systemIOMachineWeb.ts @@ -6,7 +6,6 @@ import { newKclFile } from '@src/lang/project' import { readLocalStorageProjectSettingsFile } from '@src/lib/settings/settingsUtils' import { err } from '@src/lib/trap' import { DEFAULT_DEFAULT_LENGTH_UNIT } from '@src/lib/constants' -import { codeManager, kclManager } from '@src/lib/singletons' export const systemIOMachineWeb = systemIOMachine.provide({ actors: { @@ -19,6 +18,7 @@ export const systemIOMachineWeb = systemIOMachine.provide({ requestedProjectName: string requestedFileName: string requestedCode: string + rootContext: any } }) => { // Browser version doesn't navigate, just overwrites the current file @@ -35,9 +35,9 @@ export const systemIOMachineWeb = systemIOMachine.provide({ DEFAULT_DEFAULT_LENGTH_UNIT ) if (err(codeToWrite)) return Promise.reject(codeToWrite) - codeManager.updateCodeStateEditor(codeToWrite) - await codeManager.writeToFile() - await kclManager.executeCode() + input.rootContext.codeManager.updateCodeStateEditor(codeToWrite) + await input.rootContext.codeManager.writeToFile() + await input.rootContext.kclManager.executeCode() return { message: 'File overwritten successfully', fileName: input.requestedFileName, diff --git a/src/menu/register.ts b/src/menu/register.ts index 854fefe07..62bd3a975 100644 --- a/src/menu/register.ts +++ b/src/menu/register.ts @@ -10,7 +10,7 @@ import { } from '@src/lib/singletons' import { reportRejection } from '@src/lib/trap' import { uuidv4 } from '@src/lib/utils' -import { authActor, settingsActor } from '@src/machines/appMachine' +import { authActor, settingsActor } from '@src/lib/singletons' import { commandBarActor } from '@src/machines/commandBarMachine' import type { WebContentSendPayload } from '@src/menu/channels' import type { NavigateFunction } from 'react-router-dom' diff --git a/src/routes/Home.tsx b/src/routes/Home.tsx index cfe130882..534959368 100644 --- a/src/routes/Home.tsx +++ b/src/routes/Home.tsx @@ -26,7 +26,7 @@ import { getSortIcon, } from '@src/lib/sorting' import { reportRejection } from '@src/lib/trap' -import { authActor, systemIOActor, useSettings } from '@src/machines/appMachine' +import { authActor, systemIOActor, useSettings } from '@src/lib/singletons' import { commandBarActor } from '@src/machines/commandBarMachine' import { useCanReadWriteProjectDirectory, diff --git a/src/routes/Onboarding/Camera.tsx b/src/routes/Onboarding/Camera.tsx index 04e7b50fd..211cd8e7b 100644 --- a/src/routes/Onboarding/Camera.tsx +++ b/src/routes/Onboarding/Camera.tsx @@ -1,7 +1,7 @@ import { SettingsSection } from '@src/components/Settings/SettingsSection' import type { CameraSystem } from '@src/lib/cameraControls' import { cameraMouseDragGuards, cameraSystems } from '@src/lib/cameraControls' -import { settingsActor, useSettings } from '@src/machines/appMachine' +import { settingsActor, useSettings } from '@src/lib/singletons' import { onboardingPaths } from '@src/routes/Onboarding/paths' import { diff --git a/src/routes/Onboarding/Introduction.tsx b/src/routes/Onboarding/Introduction.tsx index 80460a05e..ceb0eeb17 100644 --- a/src/routes/Onboarding/Introduction.tsx +++ b/src/routes/Onboarding/Introduction.tsx @@ -13,7 +13,7 @@ import { codeManager, kclManager } from '@src/lib/singletons' import { Themes, getSystemTheme } from '@src/lib/theme' import { reportRejection } from '@src/lib/trap' import type { IndexLoaderData } from '@src/lib/types' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' import { onboardingPaths } from '@src/routes/Onboarding/paths' import { OnboardingButtons, useDemoCode } from '@src/routes/Onboarding/utils' diff --git a/src/routes/Onboarding/ParametricModeling.tsx b/src/routes/Onboarding/ParametricModeling.tsx index 4360b5067..a3fb6fa24 100644 --- a/src/routes/Onboarding/ParametricModeling.tsx +++ b/src/routes/Onboarding/ParametricModeling.tsx @@ -1,7 +1,7 @@ import { bracketThicknessCalculationLine } from '@src/lib/exampleKcl' import { isDesktop } from '@src/lib/isDesktop' import { Themes, getSystemTheme } from '@src/lib/theme' -import { useSettings } from '@src/machines/appMachine' +import { useSettings } from '@src/lib/singletons' import { onboardingPaths } from '@src/routes/Onboarding/paths' import { OnboardingButtons, useDemoCode } from '@src/routes/Onboarding/utils' diff --git a/src/routes/Onboarding/Units.tsx b/src/routes/Onboarding/Units.tsx index 82e16235b..cbccf8e17 100644 --- a/src/routes/Onboarding/Units.tsx +++ b/src/routes/Onboarding/Units.tsx @@ -3,7 +3,7 @@ import { faArrowRight, faXmark } from '@fortawesome/free-solid-svg-icons' import { ActionButton } from '@src/components/ActionButton' import { SettingsSection } from '@src/components/Settings/SettingsSection' import { type BaseUnit, baseUnitsUnion } from '@src/lib/settings/settingsTypes' -import { settingsActor, useSettings } from '@src/machines/appMachine' +import { settingsActor, useSettings } from '@src/lib/singletons' import { onboardingPaths } from '@src/routes/Onboarding/paths' import { useDismiss, useNextClick } from '@src/routes/Onboarding/utils' diff --git a/src/routes/Onboarding/UserMenu.tsx b/src/routes/Onboarding/UserMenu.tsx index 30849812a..e3e03fee9 100644 --- a/src/routes/Onboarding/UserMenu.tsx +++ b/src/routes/Onboarding/UserMenu.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react' -import { useUser } from '@src/machines/appMachine' +import { useUser } from '@src/lib/singletons' import { onboardingPaths } from '@src/routes/Onboarding/paths' import { OnboardingButtons } from '@src/routes/Onboarding/utils' diff --git a/src/routes/Onboarding/utils.tsx b/src/routes/Onboarding/utils.tsx index 0e521b1b0..53eabbae3 100644 --- a/src/routes/Onboarding/utils.tsx +++ b/src/routes/Onboarding/utils.tsx @@ -15,7 +15,7 @@ import { PATHS } from '@src/lib/paths' import { codeManager, editorManager, kclManager } from '@src/lib/singletons' import { reportRejection } from '@src/lib/trap' import { toSync } from '@src/lib/utils' -import { settingsActor } from '@src/machines/appMachine' +import { settingsActor } from '@src/lib/singletons' import { onboardingRoutes } from '@src/routes/Onboarding' import { onboardingPaths } from '@src/routes/Onboarding/paths' diff --git a/src/routes/SignIn.tsx b/src/routes/SignIn.tsx index 40b98102b..de9c506a8 100644 --- a/src/routes/SignIn.tsx +++ b/src/routes/SignIn.tsx @@ -14,7 +14,7 @@ import { PATHS } from '@src/lib/paths' import { Themes, getSystemTheme } from '@src/lib/theme' import { reportRejection } from '@src/lib/trap' import { toSync } from '@src/lib/utils' -import { authActor, useSettings } from '@src/machines/appMachine' +import { authActor, useSettings } from '@src/lib/singletons' import { APP_VERSION, IS_NIGHTLY } from '@src/routes/utils' const subtleBorder =