Nadro/adhoc/system io machine (#6352)
* chore: saving off skeleton * fix: saving skeleton * chore: skeleton for loading projects from project directory path * chore: cleaning up useless state transition to be an on event direct to action state * fix: new structure for web vs desktop vs react machine provider code * chore: saving off skeleton * fix: skeleton logic for react? going to move it from a string to obj.string * fix: trying to prevent error element unmount on global react components. This is bricking JS state * fix: we are so back * chore: implemented navigating to specfic KCL file * chore: implementing renaming project * chore: deleting project * fix: auto fixes * fix: old debug/testing file oops * chore: generic create new file * chore: skeleton for web create file provide * chore: basic machine vitest... need to figure out how to get window.electron implemented in vitest? * chore: save off progress before deleting other project implementation, a few missing features still * chore: trying a different init skeleton? most likely will migrate * chore: first attempt of purging projects context provider * chore: enabling toast for some machine state * chore: enabling more toast success and error * chore: writing read write state to the system io based on the project path * fix: tsc fixes * fix: use file system watcher, navigate to project after creation via the requestProjectName * chore: open project command, hooks vs snapshot context helpers * chore: implemented open and create project for e2e testing. They are hard coded in poor spot for now. * fix: codespell fixes * chore: implementing more project commands * chore: PR improvements for root.tsx * chore: leaving comment about new Router.tsx layout * fix: removing debugging code * fix: rewriting component for readability * fix: improving web initialization * chore: implementing import file from url which is not actually that? * fix: clearing search params on import file from url * fix: fixed two e2e tests, forgot needsReview when making new command * fix: fixing some import from url business logic to pass e2e tests * chore: script for diffing circular deps +/- * fix: formatting * fix: massive fix for circular depsga! * fix: trying to fix some errors and auto fmt * fix: updating deps * fix: removing debugging code * fix: big clean up * fix: more deletion * fix: tsc cleanup * fix: TSC TSC TSC TSC! * fix: typo fix * fix: clear query params on web only, desktop not required * fix: removing unused code * fmt * Bring back `trap` removed in merge * Use explicit types instead of `any`s on arg configs * Add project commands directly to command palette * fix: deleting debugging code, from PR review * fix: this got added back(?) * fix: using referred type * fix: more PR clean up * fix: big block comment for xstate architecture decision * fix: more pr comment fixes * fix: merge conflict just added them back why dude * fix: more PR comments * fix: big ciruclar deps fix, commandBarActor in appActor --------- Co-authored-by: Frank Noirot <frankjohnson1993@gmail.com>
This commit is contained in:
@ -9,6 +9,26 @@ import { SceneEntities } from '@src/clientSideScene/sceneEntities'
|
||||
import { SceneInfra } from '@src/clientSideScene/sceneInfra'
|
||||
import type { BaseUnit } from '@src/lib/settings/settingsTypes'
|
||||
|
||||
import { useSelector } from '@xstate/react'
|
||||
import type { SnapshotFrom } from 'xstate'
|
||||
import { createActor, setup, assign } from 'xstate'
|
||||
|
||||
import { isDesktop } from '@src/lib/isDesktop'
|
||||
import { createSettings } from '@src/lib/settings/initialSettings'
|
||||
import { authMachine } from '@src/machines/authMachine'
|
||||
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'
|
||||
import type { AppMachineContext } from '@src/lib/types'
|
||||
import { createAuthCommands } from '@src/lib/commandBarConfigs/authCommandConfig'
|
||||
import { commandBarMachine } from '@src/machines/commandBarMachine'
|
||||
import { createProjectCommands } from '@src/lib/commandBarConfigs/projectsCommandConfig'
|
||||
|
||||
export const codeManager = new CodeManager()
|
||||
export const engineCommandManager = new EngineCommandManager()
|
||||
export const rustContext = new RustContext(engineCommandManager)
|
||||
@ -90,3 +110,122 @@ if (typeof window !== 'undefined') {
|
||||
},
|
||||
})
|
||||
}
|
||||
const { AUTH, SETTINGS, SYSTEM_IO, ENGINE_STREAM, COMMAND_BAR } = ACTOR_IDS
|
||||
const appMachineActors = {
|
||||
[AUTH]: authMachine,
|
||||
[SETTINGS]: settingsMachine,
|
||||
[SYSTEM_IO]: isDesktop() ? systemIOMachineDesktop : systemIOMachineWeb,
|
||||
[ENGINE_STREAM]: engineStreamMachine,
|
||||
[COMMAND_BAR]: commandBarMachine,
|
||||
} as const
|
||||
|
||||
const appMachine = setup({
|
||||
types: {} as {
|
||||
context: AppMachineContext
|
||||
},
|
||||
actors: appMachineActors,
|
||||
}).createMachine({
|
||||
id: 'modeling-app',
|
||||
context: {
|
||||
codeManager: codeManager,
|
||||
kclManager: kclManager,
|
||||
engineCommandManager: engineCommandManager,
|
||||
sceneInfra: sceneInfra,
|
||||
sceneEntitiesManager: sceneEntitiesManager,
|
||||
},
|
||||
entry: [
|
||||
/**
|
||||
* We originally wanted to use spawnChild but the inferred type blew up. The more children we
|
||||
* created the type complexity went through the roof. This functionally should act the same.
|
||||
* the system and parent internals are tracked properly. After reading the documentation
|
||||
* it suggests either method but this method requires manual clean up as described in the gotcha
|
||||
* comment block below. If this becomes an issue we can always move this spawn into createActor functions
|
||||
* in javascript above and reference those directly but the system and parent internals within xstate
|
||||
* will not work.
|
||||
*/
|
||||
assign({
|
||||
// Gotcha, if you use spawn, make sure you remove the ActorRef from context
|
||||
// to prevent memory leaks when the spawned actor is no longer needed
|
||||
authActor: ({ spawn }) => spawn(AUTH, { id: AUTH, systemId: AUTH }),
|
||||
settingsActor: ({ spawn }) =>
|
||||
spawn(SETTINGS, {
|
||||
id: SETTINGS,
|
||||
systemId: SETTINGS,
|
||||
input: createSettings(),
|
||||
}),
|
||||
systemIOActor: ({ spawn }) =>
|
||||
spawn(SYSTEM_IO, { id: SYSTEM_IO, systemId: SYSTEM_IO }),
|
||||
engineStreamActor: ({ spawn }) =>
|
||||
spawn(ENGINE_STREAM, {
|
||||
id: ENGINE_STREAM,
|
||||
systemId: ENGINE_STREAM,
|
||||
input: engineStreamContextCreate(),
|
||||
}),
|
||||
commandBarActor: ({ spawn }) =>
|
||||
spawn(COMMAND_BAR, {
|
||||
id: COMMAND_BAR,
|
||||
systemId: COMMAND_BAR,
|
||||
input: {
|
||||
commands: [],
|
||||
},
|
||||
}),
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
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().context.authActor!
|
||||
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().context.settingsActor!
|
||||
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().context.systemIOActor!
|
||||
|
||||
export const engineStreamActor =
|
||||
appActor.getSnapshot().context.engineStreamActor!
|
||||
|
||||
export const commandBarActor = appActor.getSnapshot().context.commandBarActor!
|
||||
|
||||
const cmdBarStateSelector = (state: SnapshotFrom<typeof commandBarActor>) =>
|
||||
state
|
||||
export const useCommandBarState = () => {
|
||||
return useSelector(commandBarActor, cmdBarStateSelector)
|
||||
}
|
||||
|
||||
// Initialize global commands
|
||||
commandBarActor.send({
|
||||
type: 'Add commands',
|
||||
data: {
|
||||
commands: [
|
||||
...createAuthCommands({ authActor }),
|
||||
...createProjectCommands({ systemIOActor }),
|
||||
],
|
||||
},
|
||||
})
|
||||
|
Reference in New Issue
Block a user