chore: saving off skeleton

This commit is contained in:
Kevin Nadro
2025-04-09 09:46:30 -05:00
parent 5d0530257c
commit 0236926cc8
10 changed files with 282 additions and 178 deletions

View File

@ -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 />

View File

@ -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)
} }
}, },

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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?

View File

@ -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 ),
}) },
}
}) })

View File

@ -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
} }
),
},
}) })

View File

@ -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
} }

View File

@ -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?