chore: saving off skeleton
This commit is contained in:
@ -20,6 +20,7 @@ import { MachineManagerProvider } from '@src/components/MachineManagerProvider'
|
|||||||
import ModelingMachineProvider from '@src/components/ModelingMachineProvider'
|
import ModelingMachineProvider from '@src/components/ModelingMachineProvider'
|
||||||
import { OpenInDesktopAppHandler } from '@src/components/OpenInDesktopAppHandler'
|
import { OpenInDesktopAppHandler } from '@src/components/OpenInDesktopAppHandler'
|
||||||
import { ProjectsContextProvider } from '@src/components/ProjectsContextProvider'
|
import { ProjectsContextProvider } from '@src/components/ProjectsContextProvider'
|
||||||
|
import { SystemIOMachineLogicListener } from '@src/components/Providers/SystemIOProviderDesktop'
|
||||||
import { RouteProvider } from '@src/components/RouteProvider'
|
import { RouteProvider } from '@src/components/RouteProvider'
|
||||||
import { WasmErrBanner } from '@src/components/WasmErrBanner'
|
import { WasmErrBanner } from '@src/components/WasmErrBanner'
|
||||||
import { NetworkContext } from '@src/hooks/useNetworkContext'
|
import { NetworkContext } from '@src/hooks/useNetworkContext'
|
||||||
@ -143,6 +144,7 @@ const router = createRouter([
|
|||||||
path: PATHS.HOME,
|
path: PATHS.HOME,
|
||||||
element: (
|
element: (
|
||||||
<Auth>
|
<Auth>
|
||||||
|
<SystemIOMachineLogicListener />
|
||||||
<Outlet />
|
<Outlet />
|
||||||
<Home />
|
<Home />
|
||||||
<CommandBar />
|
<CommandBar />
|
||||||
|
@ -229,6 +229,7 @@ const ProjectsContextDesktop = ({
|
|||||||
const newPathName = `${PATHS.FILE}/${encodeURIComponent(
|
const newPathName = `${PATHS.FILE}/${encodeURIComponent(
|
||||||
projectPath
|
projectPath
|
||||||
)}`
|
)}`
|
||||||
|
console.log(newPathName,'asdf')
|
||||||
navigate(newPathName)
|
navigate(newPathName)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
import { PATHS } from '@src/lib/paths'
|
||||||
|
import { systemIOActor } from '@src/machines/appMachine'
|
||||||
|
import { useSelector } from '@xstate/react'
|
||||||
|
import { useEffect } from 'react'
|
||||||
|
import { useNavigate } from 'react-router-dom'
|
||||||
|
import {
|
||||||
|
NO_PROJECT_DIRECTORY,
|
||||||
|
} from '@src/machines/systemIO/utils'
|
||||||
|
export const useAuthState = () => useSelector(systemIOActor, (state) => state)
|
||||||
|
|
||||||
|
|
||||||
|
export function SystemIOMachineLogicListener() {
|
||||||
|
const state = useAuthState()
|
||||||
|
useEffect(() => {
|
||||||
|
/* const requestedPath = `${PATHS.FILE}/${encodeURIComponent(
|
||||||
|
* requestedProjectName
|
||||||
|
)}`
|
||||||
|
* navigate(requestedPath) */
|
||||||
|
console.log(state)
|
||||||
|
}, [state])
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
@ -5,16 +5,14 @@ import { createSettings } from '@src/lib/settings/initialSettings'
|
|||||||
import { authMachine } from '@src/machines/authMachine'
|
import { authMachine } from '@src/machines/authMachine'
|
||||||
import { ACTOR_IDS } from '@src/machines/machineConstants'
|
import { ACTOR_IDS } from '@src/machines/machineConstants'
|
||||||
import { settingsMachine } from '@src/machines/settingsMachine'
|
import { settingsMachine } from '@src/machines/settingsMachine'
|
||||||
import { SystemIOMachineEvents } from "@src/machines/systemIO/utils"
|
import { systemIOMachineDesktop } from '@src/machines/systemIO/systemIOMachineDesktop'
|
||||||
import { systemIOMachineWeb} from "@src/machines/systemIO/systemIOMachineWeb"
|
import { SystemIOMachineEvents } from '@src/machines/systemIO/utils'
|
||||||
import { systemIOMachineDesktop} from "@src/machines/systemIO/systemIOMachineDesktop"
|
|
||||||
import { systemIOMachine} from "@src/machines/systemIO/systemIOMachine"
|
|
||||||
|
|
||||||
const { AUTH, SETTINGS, SYSTEM_IO } = ACTOR_IDS
|
const { AUTH, SETTINGS, SYSTEM_IO } = ACTOR_IDS
|
||||||
const appMachineActors = {
|
const appMachineActors = {
|
||||||
[AUTH]: authMachine,
|
[AUTH]: authMachine,
|
||||||
[SETTINGS]: settingsMachine,
|
[SETTINGS]: settingsMachine,
|
||||||
[SYSTEM_IO]: systemIOMachineDesktop
|
[SYSTEM_IO]: systemIOMachineDesktop,
|
||||||
} as const
|
} as const
|
||||||
|
|
||||||
const appMachine = setup({
|
const appMachine = setup({
|
||||||
@ -35,7 +33,7 @@ const appMachine = setup({
|
|||||||
systemId: SETTINGS,
|
systemId: SETTINGS,
|
||||||
input: createSettings(),
|
input: createSettings(),
|
||||||
}),
|
}),
|
||||||
spawnChild(SYSTEM_IO, {id: SYSTEM_IO, systemId: SYSTEM_IO})
|
spawnChild(SYSTEM_IO, { id: SYSTEM_IO, systemId: SYSTEM_IO }),
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -71,10 +69,16 @@ export const useSettings = () =>
|
|||||||
})
|
})
|
||||||
|
|
||||||
// TODO: Debugging
|
// TODO: Debugging
|
||||||
const systemIOActor = appActor.getSnapshot().children.systemIO!
|
export const systemIOActor = appActor.getSnapshot().children.systemIO!
|
||||||
|
|
||||||
// systemIOActor.send({type:SystemIOMachineEvents.readFoldersFromProjectDirectory, data: {}})
|
// systemIOActor.send({type:SystemIOMachineEvents.readFoldersFromProjectDirectory, data: {}})
|
||||||
|
|
||||||
systemIOActor.send({type:SystemIOMachineEvents.setProjectDirectoryPath, data: {requestedProjectDirectoryPath:'/home/kevin-nadro/Documents/zoo-modeling-app-projects'}})
|
systemIOActor.send({
|
||||||
|
type: SystemIOMachineEvents.setProjectDirectoryPath,
|
||||||
|
data: {
|
||||||
|
requestedProjectDirectoryPath:
|
||||||
|
'/home/kevin-nadro/Documents/zoo-modeling-app-projects',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
window.systemIOActor = systemIOActor
|
window.systemIOActor = systemIOActor
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export const ACTOR_IDS = {
|
export const ACTOR_IDS = {
|
||||||
AUTH: 'auth',
|
AUTH: 'auth',
|
||||||
SETTINGS: 'settings',
|
SETTINGS: 'settings',
|
||||||
SYSTEM_IO: 'systemIO'
|
SYSTEM_IO: 'systemIO',
|
||||||
} as const
|
} as const
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
import { setup, fromPromise, assign, assertEvent} from 'xstate'
|
import { DEFAULT_PROJECT_NAME } from '@src/lib/constants'
|
||||||
import { DEFAULT_PROJECT_NAME } from "@src/lib/constants"
|
|
||||||
import type { Project } from '@src/lib/project'
|
import type { Project } from '@src/lib/project'
|
||||||
import {SystemIOMachineEvents, SystemIOMachineActions, SystemIOMachineActors, SystemIOMachineStates, NO_PROJECT_DIRECTORY, SystemIOContext} from "@src/machines/systemIO/utils"
|
import type {
|
||||||
|
SystemIOContext} from '@src/machines/systemIO/utils'
|
||||||
|
import {
|
||||||
|
NO_PROJECT_DIRECTORY,
|
||||||
|
SystemIOMachineActions,
|
||||||
|
SystemIOMachineActors,
|
||||||
|
SystemIOMachineEvents,
|
||||||
|
SystemIOMachineStates,
|
||||||
|
} from '@src/machines/systemIO/utils'
|
||||||
|
import { assertEvent, assign, fromPromise, setup } from 'xstate'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles any system level I/O for folders and files
|
* Handles any system level I/O for folders and files
|
||||||
@ -13,31 +21,57 @@ export const systemIOMachine = setup({
|
|||||||
types: {
|
types: {
|
||||||
context: {} as SystemIOContext,
|
context: {} as SystemIOContext,
|
||||||
events: {} as
|
events: {} as
|
||||||
| { type: SystemIOMachineEvents.readFoldersFromProjectDirectory; data: {} }
|
| {
|
||||||
| { type: SystemIOMachineEvents.done_readFoldersFromProjectDirectory; data: {}, output: Project[] }
|
type: SystemIOMachineEvents.readFoldersFromProjectDirectory
|
||||||
| { type: SystemIOMachineEvents.setProjectDirectoryPath; data: {requestedProjectDirectoryPath: string}}
|
data: {}
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: SystemIOMachineEvents.done_readFoldersFromProjectDirectory
|
||||||
|
data: {}
|
||||||
|
output: Project[]
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: SystemIOMachineEvents.setProjectDirectoryPath
|
||||||
|
data: { requestedProjectDirectoryPath: string }
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: SystemIOMachineEvents.openProject
|
||||||
|
data: { requestedProjectName: string }
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
[SystemIOMachineActions.setFolders]: assign({
|
[SystemIOMachineActions.setFolders]: assign({
|
||||||
folders:({event})=>{
|
folders: ({ event }) => {
|
||||||
assertEvent(event, SystemIOMachineEvents.done_readFoldersFromProjectDirectory)
|
assertEvent(
|
||||||
|
event,
|
||||||
|
SystemIOMachineEvents.done_readFoldersFromProjectDirectory
|
||||||
|
)
|
||||||
return event.output
|
return event.output
|
||||||
}
|
},
|
||||||
}),
|
}),
|
||||||
[SystemIOMachineActions.setProjectDirectoryPath]: assign({
|
[SystemIOMachineActions.setProjectDirectoryPath]: assign({
|
||||||
projectDirectoryPath:({event})=>{
|
projectDirectoryPath: ({ event }) => {
|
||||||
assertEvent(event, SystemIOMachineEvents.setProjectDirectoryPath)
|
assertEvent(event, SystemIOMachineEvents.setProjectDirectoryPath)
|
||||||
return event.data.requestedProjectDirectoryPath
|
return event.data.requestedProjectDirectoryPath
|
||||||
}
|
},
|
||||||
})
|
}),
|
||||||
|
[SystemIOMachineActions.setRequestedProjectName]: assign({
|
||||||
|
requestedProjectName: ({ event }) => {
|
||||||
|
assertEvent(event, SystemIOMachineEvents.openProject)
|
||||||
|
console.log('event', event.data.requestedProjectName)
|
||||||
|
return event.data.requestedProjectName
|
||||||
|
},
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
actors: {
|
actors: {
|
||||||
[SystemIOMachineActors.readFoldersFromProjectDirectory]: fromPromise(async ({input:context}:{input:SystemIOContext}) => {
|
[SystemIOMachineActors.readFoldersFromProjectDirectory]: fromPromise(
|
||||||
return []
|
async ({ input: context }: { input: SystemIOContext }) => {
|
||||||
}),
|
return []
|
||||||
}
|
}
|
||||||
|
),
|
||||||
|
},
|
||||||
}).createMachine({
|
}).createMachine({
|
||||||
initial:SystemIOMachineStates.idle,
|
initial: SystemIOMachineStates.idle,
|
||||||
// Remember, this machine and change its projectDirectory at any point
|
// Remember, this machine and change its projectDirectory at any point
|
||||||
// '' will be no project directory, aka clear this machine out!
|
// '' will be no project directory, aka clear this machine out!
|
||||||
// To be the aboslute root of someones computer we should take the string of path.resolve() in node.js which is different for each OS
|
// To be the aboslute root of someones computer we should take the string of path.resolve() in node.js which is different for each OS
|
||||||
@ -45,43 +79,46 @@ export const systemIOMachine = setup({
|
|||||||
folders: [],
|
folders: [],
|
||||||
defaultProjectFolderName: DEFAULT_PROJECT_NAME,
|
defaultProjectFolderName: DEFAULT_PROJECT_NAME,
|
||||||
projectDirectoryPath: NO_PROJECT_DIRECTORY,
|
projectDirectoryPath: NO_PROJECT_DIRECTORY,
|
||||||
hasListedProjects: false
|
hasListedProjects: false,
|
||||||
|
requestedProjectName: NO_PROJECT_DIRECTORY,
|
||||||
}),
|
}),
|
||||||
states: {
|
states: {
|
||||||
[SystemIOMachineStates.idle]: {
|
[SystemIOMachineStates.idle]: {
|
||||||
on: {
|
on: {
|
||||||
// on can be an action
|
// on can be an action
|
||||||
[SystemIOMachineEvents.readFoldersFromProjectDirectory]:SystemIOMachineStates.readingFolders,
|
[SystemIOMachineEvents.readFoldersFromProjectDirectory]:
|
||||||
[SystemIOMachineEvents.setProjectDirectoryPath]:{
|
SystemIOMachineStates.readingFolders,
|
||||||
|
[SystemIOMachineEvents.setProjectDirectoryPath]: {
|
||||||
target: SystemIOMachineStates.readingFolders,
|
target: SystemIOMachineStates.readingFolders,
|
||||||
actions: [
|
actions: [SystemIOMachineActions.setProjectDirectoryPath],
|
||||||
SystemIOMachineActions.setProjectDirectoryPath
|
},
|
||||||
]
|
[SystemIOMachineEvents.openProject]: {
|
||||||
}
|
target: SystemIOMachineStates.openingProject,
|
||||||
}
|
actions: [SystemIOMachineActions.setRequestedProjectName],
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
[SystemIOMachineStates.readingFolders]: {
|
[SystemIOMachineStates.readingFolders]: {
|
||||||
invoke: {
|
invoke: {
|
||||||
id: SystemIOMachineActors.readFoldersFromProjectDirectory,
|
id: SystemIOMachineActors.readFoldersFromProjectDirectory,
|
||||||
src: SystemIOMachineActors.readFoldersFromProjectDirectory,
|
src: SystemIOMachineActors.readFoldersFromProjectDirectory,
|
||||||
input: ({context}) => {
|
input: ({ context }) => {
|
||||||
return context
|
return context
|
||||||
},
|
},
|
||||||
onDone: {
|
onDone: {
|
||||||
target: SystemIOMachineStates.idle,
|
target: SystemIOMachineStates.idle,
|
||||||
actions: [
|
actions: [SystemIOMachineActions.setFolders],
|
||||||
SystemIOMachineActions.setFolders
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
onError: {
|
onError: {
|
||||||
target: SystemIOMachineStates.idle,
|
target: SystemIOMachineStates.idle,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
[SystemIOMachineStates.openingProject] : {
|
||||||
|
}
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// Watcher handler
|
// Watcher handler
|
||||||
// look at projectDirectory useEffect then send this event if it changes or if we need to do this?
|
// look at projectDirectory useEffect then send this event if it changes or if we need to do this?
|
||||||
// The handler needs to live somewhere... aka the provider?
|
// The handler needs to live somewhere... aka the provider?
|
||||||
|
@ -1,47 +1,58 @@
|
|||||||
import { SystemIOMachineEvents, SystemIOMachineActors, SystemIOContext, NO_PROJECT_DIRECTORY} from "@src/machines/systemIO/utils"
|
import { getProjectInfo, mkdirOrNOOP } from '@src/lib/desktop'
|
||||||
import { systemIOMachine} from "@src/machines/systemIO/systemIOMachine"
|
|
||||||
import { setup, fromPromise, assign, assertEvent} from 'xstate'
|
|
||||||
import { mkdirOrNOOP, getProjectInfo } from "@src/lib/desktop"
|
|
||||||
import type { Project } from '@src/lib/project'
|
import type { Project } from '@src/lib/project'
|
||||||
|
import { systemIOMachine } from '@src/machines/systemIO/systemIOMachine'
|
||||||
|
import type {
|
||||||
|
SystemIOContext} from '@src/machines/systemIO/utils'
|
||||||
|
import {
|
||||||
|
NO_PROJECT_DIRECTORY,
|
||||||
|
SystemIOMachineActors,
|
||||||
|
} from '@src/machines/systemIO/utils'
|
||||||
|
import { fromPromise } from 'xstate'
|
||||||
|
|
||||||
export const systemIOMachineDesktop = systemIOMachine.provide({
|
export const systemIOMachineDesktop = systemIOMachine.provide({
|
||||||
actors: {
|
actors: {
|
||||||
[SystemIOMachineActors.readFoldersFromProjectDirectory]: fromPromise(async ({input:context}:{input:SystemIOContext}) => {
|
[SystemIOMachineActors.readFoldersFromProjectDirectory]: fromPromise(
|
||||||
const projects = []
|
async ({ input: context }: { input: SystemIOContext }) => {
|
||||||
const projectDirectoryPath = context.projectDirectoryPath
|
const projects = []
|
||||||
if (projectDirectoryPath === NO_PROJECT_DIRECTORY) {
|
const projectDirectoryPath = context.projectDirectoryPath
|
||||||
// TODO
|
if (projectDirectoryPath === NO_PROJECT_DIRECTORY) {
|
||||||
return []
|
// TODO
|
||||||
}
|
return []
|
||||||
await mkdirOrNOOP(projectDirectoryPath)
|
}
|
||||||
// Gotcha: readdir will list all folders at this project directory even if you do not have readwrite access on the directory path
|
await mkdirOrNOOP(projectDirectoryPath)
|
||||||
const entries = await window.electron.readdir(projectDirectoryPath)
|
// Gotcha: readdir will list all folders at this project directory even if you do not have readwrite access on the directory path
|
||||||
const { value: canReadWriteProjectDirectory } = await window.electron.canReadWriteDirectory(projectDirectoryPath)
|
const entries = await window.electron.readdir(projectDirectoryPath)
|
||||||
|
const { value: canReadWriteProjectDirectory } =
|
||||||
|
await window.electron.canReadWriteDirectory(projectDirectoryPath)
|
||||||
|
|
||||||
for (let entry of entries) {
|
for (let entry of entries) {
|
||||||
// Skip directories that start with a dot
|
// Skip directories that start with a dot
|
||||||
if (entry.startsWith('.')) {
|
if (entry.startsWith('.')) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const projectPath = window.electron.path.join(projectDirectoryPath, entry)
|
const projectPath = window.electron.path.join(
|
||||||
|
projectDirectoryPath,
|
||||||
|
entry
|
||||||
|
)
|
||||||
|
|
||||||
// if it's not a directory ignore.
|
// if it's not a directory ignore.
|
||||||
// Gotcha: statIsDirectory will work even if you do not have read write permissions on the project path
|
// Gotcha: statIsDirectory will work even if you do not have read write permissions on the project path
|
||||||
const isDirectory = await window.electron.statIsDirectory(projectPath)
|
const isDirectory = await window.electron.statIsDirectory(projectPath)
|
||||||
if (!isDirectory) {
|
if (!isDirectory) {
|
||||||
continue
|
continue
|
||||||
|
}
|
||||||
|
const project: Project = await getProjectInfo(projectPath)
|
||||||
|
if (
|
||||||
|
project.kcl_file_count === 0 &&
|
||||||
|
project.readWriteAccess &&
|
||||||
|
canReadWriteProjectDirectory
|
||||||
|
) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
projects.push(project)
|
||||||
}
|
}
|
||||||
const project : Project = await getProjectInfo(projectPath)
|
return projects
|
||||||
if (
|
|
||||||
project.kcl_file_count === 0 &&
|
|
||||||
project.readWriteAccess &&
|
|
||||||
canReadWriteProjectDirectory
|
|
||||||
) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
projects.push(project)
|
|
||||||
}
|
}
|
||||||
return projects
|
),
|
||||||
})
|
},
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
import { SystemIOMachineEvents, SystemIOMachineActors, SystemIOContext} from "@src/machines/systemIO/utils"
|
|
||||||
import { systemIOMachine} from "@src/machines/systemIO/systemIOMachine"
|
|
||||||
import { setup, fromPromise, assign, assertEvent} from 'xstate'
|
|
||||||
import type { Project } from '@src/lib/project'
|
import type { Project } from '@src/lib/project'
|
||||||
|
import { systemIOMachine } from '@src/machines/systemIO/systemIOMachine'
|
||||||
|
import type {
|
||||||
|
SystemIOContext} from '@src/machines/systemIO/utils'
|
||||||
|
import {
|
||||||
|
SystemIOMachineActors,
|
||||||
|
} from '@src/machines/systemIO/utils'
|
||||||
|
import { fromPromise } from 'xstate'
|
||||||
|
|
||||||
export const systemIOMachineWeb = systemIOMachine.provide({
|
export const systemIOMachineWeb = systemIOMachine.provide({
|
||||||
actors: {
|
actors: {
|
||||||
[SystemIOMachineActors.readFoldersFromProjectDirectory]: fromPromise(async ({input:context}:{input:SystemIOContext}) => {
|
[SystemIOMachineActors.readFoldersFromProjectDirectory]: fromPromise(
|
||||||
const projects: Project[] = []
|
async ({ input: context }: { input: SystemIOContext }) => {
|
||||||
console.log('nothing!')
|
const projects: Project[] = []
|
||||||
return projects
|
console.log('nothing!')
|
||||||
})
|
return projects
|
||||||
}
|
}
|
||||||
|
),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
@ -1,40 +1,45 @@
|
|||||||
import type { Project } from '@src/lib/project'
|
import type { Project } from '@src/lib/project'
|
||||||
|
|
||||||
export enum SystemIOMachineActors {
|
export enum SystemIOMachineActors {
|
||||||
readFoldersFromProjectDirectory = "read folders from project directory",
|
readFoldersFromProjectDirectory = 'read folders from project directory',
|
||||||
setProjectDirectoryPath = "set project directory path"
|
setProjectDirectoryPath = 'set project directory path',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SystemIOMachineStates {
|
export enum SystemIOMachineStates {
|
||||||
idle = "idle",
|
idle = 'idle',
|
||||||
readingFolders = "readingFolders",
|
readingFolders = 'readingFolders',
|
||||||
settingProjectDirectoryPath = "settingProjectDirectoryPath"
|
settingProjectDirectoryPath = 'settingProjectDirectoryPath',
|
||||||
|
openingProject = 'openingProject'
|
||||||
}
|
}
|
||||||
|
|
||||||
const donePrefix = 'xstate.done.actor.'
|
const donePrefix = 'xstate.done.actor.'
|
||||||
|
|
||||||
export enum SystemIOMachineEvents {
|
export enum SystemIOMachineEvents {
|
||||||
readFoldersFromProjectDirectory = "read folders from project directory",
|
readFoldersFromProjectDirectory = 'read folders from project directory',
|
||||||
done_readFoldersFromProjectDirectory = donePrefix + "read folders from project directory",
|
done_readFoldersFromProjectDirectory = donePrefix +
|
||||||
setProjectDirectoryPath = "set project directory path",
|
'read folders from project directory',
|
||||||
|
setProjectDirectoryPath = 'set project directory path',
|
||||||
|
openProject = 'open project',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SystemIOMachineActions {
|
export enum SystemIOMachineActions {
|
||||||
setFolders = "set folders",
|
setFolders = 'set folders',
|
||||||
setProjectDirectoryPath = "set project directory path"
|
setProjectDirectoryPath = 'set project directory path',
|
||||||
|
setRequestedProjectName = 'set requested project name',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const NO_PROJECT_DIRECTORY = ''
|
export const NO_PROJECT_DIRECTORY = ''
|
||||||
|
|
||||||
export type SystemIOContext = {
|
export type SystemIOContext = {
|
||||||
// Only store folders under the projectDirectory, do not maintain folders outside this directory
|
// Only store folders under the projectDirectory, do not maintain folders outside this directory
|
||||||
folders: Project[],
|
folders: Project[]
|
||||||
// For this machines runtime, this is the default string when creating a project
|
// For this machines runtime, this is the default string when creating a project
|
||||||
// A project is defined by creating a folder at the one level below the working project directory
|
// A project is defined by creating a folder at the one level below the working project directory
|
||||||
defaultProjectFolderName:string,
|
defaultProjectFolderName: string
|
||||||
// working project directory that stores all the project folders
|
// working project directory that stores all the project folders
|
||||||
projectDirectoryPath: string,
|
projectDirectoryPath: string
|
||||||
// has the application gone through the initialiation of systemIOMachine at least once.
|
// has the application gone through the initialiation of systemIOMachine at least once.
|
||||||
// this is required to prevent chokidar from spamming invalid events during initialization.
|
// this is required to prevent chokidar from spamming invalid events during initialization.
|
||||||
hasListedProjects: boolean
|
hasListedProjects: boolean
|
||||||
|
requestedProjectName: string
|
||||||
}
|
}
|
||||||
|
@ -1,42 +1,43 @@
|
|||||||
import { setup, fromPromise, assign, assertEvent} from 'xstate'
|
import { DEFAULT_PROJECT_NAME } from '@src/lib/constants'
|
||||||
import { DEFAULT_PROJECT_NAME } from "@src/lib/constants"
|
import { getProjectInfo, mkdirOrNOOP } from '@src/lib/desktop'
|
||||||
import { mkdirOrNOOP, getProjectInfo } from "@src/lib/desktop"
|
|
||||||
import type { Project } from '@src/lib/project'
|
import type { Project } from '@src/lib/project'
|
||||||
|
import { assertEvent, assign, fromPromise, setup } from 'xstate'
|
||||||
|
|
||||||
export enum SystemIOMachineActors {
|
export enum SystemIOMachineActors {
|
||||||
readFoldersFromProjectDirectory = "read folders from project directory",
|
readFoldersFromProjectDirectory = 'read folders from project directory',
|
||||||
setProjectDirectoryPath = "set project directory path"
|
setProjectDirectoryPath = 'set project directory path',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SystemIOMachineStates {
|
export enum SystemIOMachineStates {
|
||||||
idle = "idle",
|
idle = 'idle',
|
||||||
readingFolders = "readingFolders",
|
readingFolders = 'readingFolders',
|
||||||
settingProjectDirectoryPath = "settingProjectDirectoryPath"
|
settingProjectDirectoryPath = 'settingProjectDirectoryPath',
|
||||||
}
|
}
|
||||||
|
|
||||||
const donePrefix = 'xstate.done.actor.'
|
const donePrefix = 'xstate.done.actor.'
|
||||||
|
|
||||||
export enum SystemIOMachineEvents {
|
export enum SystemIOMachineEvents {
|
||||||
readFoldersFromProjectDirectory = "read folders from project directory",
|
readFoldersFromProjectDirectory = 'read folders from project directory',
|
||||||
done_readFoldersFromProjectDirectory = donePrefix + "read folders from project directory",
|
done_readFoldersFromProjectDirectory = donePrefix +
|
||||||
setProjectDirectoryPath = "set project directory path",
|
'read folders from project directory',
|
||||||
|
setProjectDirectoryPath = 'set project directory path',
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum SystemIOMachineActions {
|
export enum SystemIOMachineActions {
|
||||||
setFolders = "set folders",
|
setFolders = 'set folders',
|
||||||
setProjectDirectoryPath = "set project directory path"
|
setProjectDirectoryPath = 'set project directory path',
|
||||||
}
|
}
|
||||||
|
|
||||||
const NO_PROJECT_DIRECTORY = ''
|
const NO_PROJECT_DIRECTORY = ''
|
||||||
|
|
||||||
export type SystemIOContext = {
|
export type SystemIOContext = {
|
||||||
// Only store folders under the projectDirectory, do not maintain folders outside this directory
|
// Only store folders under the projectDirectory, do not maintain folders outside this directory
|
||||||
folders: Project[],
|
folders: Project[]
|
||||||
// For this machines runtime, this is the default string when creating a project
|
// For this machines runtime, this is the default string when creating a project
|
||||||
// A project is defined by creating a folder at the one level below the working project directory
|
// A project is defined by creating a folder at the one level below the working project directory
|
||||||
defaultProjectFolderName:string,
|
defaultProjectFolderName: string
|
||||||
// working project directory that stores all the project folders
|
// working project directory that stores all the project folders
|
||||||
projectDirectoryPath: string,
|
projectDirectoryPath: string
|
||||||
// has the application gone through the initialiation of systemIOMachine at least once.
|
// has the application gone through the initialiation of systemIOMachine at least once.
|
||||||
// this is required to prevent chokidar from spamming invalid events during initialization.
|
// this is required to prevent chokidar from spamming invalid events during initialization.
|
||||||
hasListedProjects: boolean
|
hasListedProjects: boolean
|
||||||
@ -52,65 +53,84 @@ export const systemIOMachine = setup({
|
|||||||
types: {
|
types: {
|
||||||
context: {} as SystemIOContext,
|
context: {} as SystemIOContext,
|
||||||
events: {} as
|
events: {} as
|
||||||
| { type: SystemIOMachineEvents.readFoldersFromProjectDirectory; data: {} }
|
| {
|
||||||
| { type: SystemIOMachineEvents.done_readFoldersFromProjectDirectory; data: {}, output: Project[] }
|
type: SystemIOMachineEvents.readFoldersFromProjectDirectory
|
||||||
| { type: SystemIOMachineEvents.setProjectDirectoryPath; data: {requestedProjectDirectoryPath: string}}
|
data: {}
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: SystemIOMachineEvents.done_readFoldersFromProjectDirectory
|
||||||
|
data: {}
|
||||||
|
output: Project[]
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
type: SystemIOMachineEvents.setProjectDirectoryPath
|
||||||
|
data: { requestedProjectDirectoryPath: string }
|
||||||
|
},
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
[SystemIOMachineActions.setFolders]: assign({
|
[SystemIOMachineActions.setFolders]: assign({
|
||||||
folders:({event})=>{
|
folders: ({ event }) => {
|
||||||
assertEvent(event, SystemIOMachineEvents.done_readFoldersFromProjectDirectory)
|
assertEvent(
|
||||||
|
event,
|
||||||
|
SystemIOMachineEvents.done_readFoldersFromProjectDirectory
|
||||||
|
)
|
||||||
return event.output
|
return event.output
|
||||||
}
|
},
|
||||||
}),
|
}),
|
||||||
[SystemIOMachineActions.setProjectDirectoryPath]: assign({
|
[SystemIOMachineActions.setProjectDirectoryPath]: assign({
|
||||||
projectDirectoryPath:({event})=>{
|
projectDirectoryPath: ({ event }) => {
|
||||||
assertEvent(event, SystemIOMachineEvents.setProjectDirectoryPath)
|
assertEvent(event, SystemIOMachineEvents.setProjectDirectoryPath)
|
||||||
return event.data.requestedProjectDirectoryPath
|
return event.data.requestedProjectDirectoryPath
|
||||||
}
|
},
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
actors: {
|
actors: {
|
||||||
[SystemIOMachineActors.readFoldersFromProjectDirectory]: fromPromise(async ({input:context}:{input:SystemIOContext}) => {
|
[SystemIOMachineActors.readFoldersFromProjectDirectory]: fromPromise(
|
||||||
const projects = []
|
async ({ input: context }: { input: SystemIOContext }) => {
|
||||||
const projectDirectoryPath = context.projectDirectoryPath
|
const projects = []
|
||||||
if (projectDirectoryPath === NO_PROJECT_DIRECTORY) {
|
const projectDirectoryPath = context.projectDirectoryPath
|
||||||
// TODO
|
if (projectDirectoryPath === NO_PROJECT_DIRECTORY) {
|
||||||
return []
|
// TODO
|
||||||
}
|
return []
|
||||||
await mkdirOrNOOP(projectDirectoryPath)
|
}
|
||||||
// Gotcha: readdir will list all folders at this project directory even if you do not have readwrite access on the directory path
|
await mkdirOrNOOP(projectDirectoryPath)
|
||||||
const entries = await window.electron.readdir(projectDirectoryPath)
|
// Gotcha: readdir will list all folders at this project directory even if you do not have readwrite access on the directory path
|
||||||
const { value: canReadWriteProjectDirectory } = await window.electron.canReadWriteDirectory(projectDirectoryPath)
|
const entries = await window.electron.readdir(projectDirectoryPath)
|
||||||
|
const { value: canReadWriteProjectDirectory } =
|
||||||
|
await window.electron.canReadWriteDirectory(projectDirectoryPath)
|
||||||
|
|
||||||
for (let entry of entries) {
|
for (let entry of entries) {
|
||||||
// Skip directories that start with a dot
|
// Skip directories that start with a dot
|
||||||
if (entry.startsWith('.')) {
|
if (entry.startsWith('.')) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
const projectPath = window.electron.path.join(projectDirectoryPath, entry)
|
const projectPath = window.electron.path.join(
|
||||||
|
projectDirectoryPath,
|
||||||
|
entry
|
||||||
|
)
|
||||||
|
|
||||||
// if it's not a directory ignore.
|
// if it's not a directory ignore.
|
||||||
// Gotcha: statIsDirectory will work even if you do not have read write permissions on the project path
|
// Gotcha: statIsDirectory will work even if you do not have read write permissions on the project path
|
||||||
const isDirectory = await window.electron.statIsDirectory(projectPath)
|
const isDirectory = await window.electron.statIsDirectory(projectPath)
|
||||||
if (!isDirectory) {
|
if (!isDirectory) {
|
||||||
continue
|
continue
|
||||||
|
}
|
||||||
|
const project: Project = await getProjectInfo(projectPath)
|
||||||
|
if (
|
||||||
|
project.kcl_file_count === 0 &&
|
||||||
|
project.readWriteAccess &&
|
||||||
|
canReadWriteProjectDirectory
|
||||||
|
) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
projects.push(project)
|
||||||
}
|
}
|
||||||
const project : Project = await getProjectInfo(projectPath)
|
return projects
|
||||||
if (
|
|
||||||
project.kcl_file_count === 0 &&
|
|
||||||
project.readWriteAccess &&
|
|
||||||
canReadWriteProjectDirectory
|
|
||||||
) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
projects.push(project)
|
|
||||||
}
|
}
|
||||||
return projects
|
),
|
||||||
}),
|
},
|
||||||
}
|
|
||||||
}).createMachine({
|
}).createMachine({
|
||||||
initial:SystemIOMachineStates.idle,
|
initial: SystemIOMachineStates.idle,
|
||||||
// Remember, this machine and change its projectDirectory at any point
|
// Remember, this machine and change its projectDirectory at any point
|
||||||
// '' will be no project directory, aka clear this machine out!
|
// '' will be no project directory, aka clear this machine out!
|
||||||
// To be the aboslute root of someones computer we should take the string of path.resolve() in node.js which is different for each OS
|
// To be the aboslute root of someones computer we should take the string of path.resolve() in node.js which is different for each OS
|
||||||
@ -118,43 +138,39 @@ export const systemIOMachine = setup({
|
|||||||
folders: [],
|
folders: [],
|
||||||
defaultProjectFolderName: DEFAULT_PROJECT_NAME,
|
defaultProjectFolderName: DEFAULT_PROJECT_NAME,
|
||||||
projectDirectoryPath: NO_PROJECT_DIRECTORY,
|
projectDirectoryPath: NO_PROJECT_DIRECTORY,
|
||||||
hasListedProjects: false
|
hasListedProjects: false,
|
||||||
}),
|
}),
|
||||||
states: {
|
states: {
|
||||||
[SystemIOMachineStates.idle]: {
|
[SystemIOMachineStates.idle]: {
|
||||||
on: {
|
on: {
|
||||||
// on can be an action
|
// on can be an action
|
||||||
[SystemIOMachineEvents.readFoldersFromProjectDirectory]:SystemIOMachineStates.readingFolders,
|
[SystemIOMachineEvents.readFoldersFromProjectDirectory]:
|
||||||
[SystemIOMachineEvents.setProjectDirectoryPath]:{
|
SystemIOMachineStates.readingFolders,
|
||||||
|
[SystemIOMachineEvents.setProjectDirectoryPath]: {
|
||||||
target: SystemIOMachineStates.readingFolders,
|
target: SystemIOMachineStates.readingFolders,
|
||||||
actions: [
|
actions: [SystemIOMachineActions.setProjectDirectoryPath],
|
||||||
SystemIOMachineActions.setProjectDirectoryPath
|
},
|
||||||
]
|
},
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[SystemIOMachineStates.readingFolders]: {
|
[SystemIOMachineStates.readingFolders]: {
|
||||||
invoke: {
|
invoke: {
|
||||||
id: SystemIOMachineActors.readFoldersFromProjectDirectory,
|
id: SystemIOMachineActors.readFoldersFromProjectDirectory,
|
||||||
src: SystemIOMachineActors.readFoldersFromProjectDirectory,
|
src: SystemIOMachineActors.readFoldersFromProjectDirectory,
|
||||||
input: ({context}) => {
|
input: ({ context }) => {
|
||||||
return context
|
return context
|
||||||
},
|
},
|
||||||
onDone: {
|
onDone: {
|
||||||
target: SystemIOMachineStates.idle,
|
target: SystemIOMachineStates.idle,
|
||||||
actions: [
|
actions: [SystemIOMachineActions.setFolders],
|
||||||
SystemIOMachineActions.setFolders
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
onError: {
|
onError: {
|
||||||
target: SystemIOMachineStates.idle,
|
target: SystemIOMachineStates.idle,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
// Watcher handler
|
// Watcher handler
|
||||||
// look at projectDirectory useEffect then send this event if it changes or if we need to do this?
|
// look at projectDirectory useEffect then send this event if it changes or if we need to do this?
|
||||||
// The handler needs to live somewhere... aka the provider?
|
// The handler needs to live somewhere... aka the provider?
|
||||||
|
Reference in New Issue
Block a user