Compare commits

...

1 Commits

Author SHA1 Message Date
8424355a07 xstate v5 rough start 2024-02-19 20:51:29 +11:00
14 changed files with 289 additions and 259 deletions

View File

@ -27,7 +27,7 @@
"@types/react-dom": "^18.0.0",
"@uiw/react-codemirror": "^4.21.20",
"@xstate/inspect": "^0.8.0",
"@xstate/react": "^3.2.2",
"@xstate/react": "^4.1.0",
"crypto-js": "^4.2.0",
"debounce-promise": "^3.1.2",
"formik": "^2.4.3",
@ -57,7 +57,7 @@
"wasm-pack": "^0.12.1",
"web-vitals": "^3.5.0",
"ws": "^8.13.0",
"xstate": "^4.38.2",
"xstate": "^5.7.1",
"zustand": "^4.4.5"
},
"scripts": {

View File

@ -72,7 +72,7 @@ export function App() {
useHotkeys('shift + l', () => togglePane('logs'))
useHotkeys('shift + e', () => togglePane('kclErrors'))
useHotkeys('shift + d', () => togglePane('debug'))
useHotkeys('esc', () => send('Cancel'))
useHotkeys('esc', () => send({ type: 'Cancel' }))
useHotkeys('backspace', (e) => {
e.preventDefault()
})

View File

@ -100,8 +100,8 @@ export const Toolbar = () => {
Element="button"
onClick={() =>
state?.matches('Sketch.Line tool')
? send('CancelSketch')
: send('Equip Line tool')
? send({ type: 'CancelSketch' })
: send({ type: 'Equip Line tool' })
}
aria-pressed={state?.matches('Sketch.Line tool')}
className="pressed:bg-energy-10/20 dark:pressed:bg-energy-80"
@ -118,8 +118,8 @@ export const Toolbar = () => {
Element="button"
onClick={() =>
state.matches('Sketch.Tangential arc to')
? send('CancelSketch')
: send('Equip tangential arc to')
? send({ type: 'CancelSketch' })
: send({ type: 'Equip tangential arc to' })
}
aria-pressed={state.matches('Sketch.Tangential arc to')}
className="pressed:bg-energy-10/20 dark:pressed:bg-energy-80"
@ -128,7 +128,7 @@ export const Toolbar = () => {
bgClassName,
}}
disabled={
!state.can('Equip tangential arc to') &&
!state.can({ type: 'Equip tangential arc to' }) &&
!state.matches('Sketch.Tangential arc to')
}
>
@ -194,9 +194,9 @@ export const Toolbar = () => {
data: { name: 'Extrude', ownerMachine: 'modeling' },
})
}
disabled={!state.can('Extrude')}
disabled={!state.can({ type: 'Extrude' })}
title={
state.can('Extrude')
state.can({ type: 'Extrude' })
? 'extrude'
: 'sketches need to be closed, or not already extruded'
}

View File

@ -26,15 +26,16 @@ export const CommandBarProvider = ({
children: React.ReactNode
}) => {
const { pathname } = useLocation()
const [commandBarState, commandBarSend] = useMachine(commandBarMachine, {
const [commandBarState, commandBarSend] = useMachine(
commandBarMachine.provide({
guards: {
'Arguments are ready': (context, _) => {
'Arguments are ready': ({ context }) => {
return context.selectedCommand?.args
? context.argumentsToSubmit.length ===
Object.keys(context.selectedCommand.args)?.length
: false
},
'Command has no arguments': (context, _event) => {
'Command has no arguments': ({ context }) => {
return (
!context.selectedCommand?.args ||
Object.keys(context.selectedCommand?.args).length === 0
@ -42,6 +43,7 @@ export const CommandBarProvider = ({
},
},
})
)
// Close the command bar when navigating
useEffect(() => {

View File

@ -44,16 +44,14 @@ export const FileMachineProvider = ({
const { commandBarSend } = useCommandsContext()
const { project } = useRouteLoaderData(paths.FILE) as IndexLoaderData
const [state, send] = useMachine(fileMachine, {
const [state, send] = useMachine(
fileMachine.provide({
context: {
project,
selectedDirectory: project,
},
actions: {
navigateToFile: (
context: ContextFrom<typeof fileMachine>,
event: EventFrom<typeof fileMachine>
) => {
navigateToFile: ({ context, event }) => {
if (event.data && 'name' in event.data) {
commandBarSend({ type: 'Close' })
navigate(
@ -63,9 +61,9 @@ export const FileMachineProvider = ({
)
}
},
toastSuccess: (_, event) =>
toastSuccess: ({ event }) =>
event.data && toast.success((event.data || '') + ''),
toastError: (_, event) => toast.error((event.data || '') + ''),
toastError: ({ event }) => toast.error((event.data || '') + ''),
},
services: {
readFiles: async (context: ContextFrom<typeof fileMachine>) => {
@ -136,12 +134,13 @@ export const FileMachineProvider = ({
},
},
guards: {
'Has at least 1 file': (_, event: EventFrom<typeof fileMachine>) => {
'Has at least 1 file': ({ event }) => {
if (event.type !== 'done.invoke.read-files') return false
return !!event?.data?.children && event.data.children.length > 0
},
},
})
)
return (
<FileContext.Provider

View File

@ -85,7 +85,7 @@ export const ModelingMachineProvider = ({
'sketch exit execute': () => {
kclManager.executeAst()
},
'Set selection': assign(({ selectionRanges }, event) => {
'Set selection': assign(({ context: { selectionRanges }, event }) => {
if (event.type !== 'Set selection') return {} // this was needed for ts after adding 'Set selection' action to on done modal events
const setSelections = event.data
if (!editorView) return {}
@ -172,7 +172,7 @@ export const ModelingMachineProvider = ({
}),
},
guards: {
'has valid extrude selection': ({ selectionRanges }) => {
'has valid extrude selection': ({ context: { selectionRanges } }) => {
// A user can begin extruding if they either have 1+ faces selected or nothing selected
// TODO: I believe this guard only allows for extruding a single face at a time
if (selectionRanges.codeBasedSelections.length < 1) return false
@ -183,7 +183,10 @@ export const ModelingMachineProvider = ({
return canExtrudeSelection(selectionRanges)
},
'Selection is on face': ({ selectionRanges }, { data }) => {
'Selection is on face': ({
context: { selectionRanges },
event: { data },
}) => {
if (data?.forceNewSketch) return false
if (!isSingleCursorInPipe(selectionRanges, kclManager.ast))
return false
@ -194,7 +197,7 @@ export const ModelingMachineProvider = ({
},
},
services: {
'AST-undo-startSketchOn': async ({ sketchPathToNode }) => {
'AST-undo-startSketchOn': async ({ context: { sketchPathToNode } }) => {
if (!sketchPathToNode) return
const newAst: Program = JSON.parse(JSON.stringify(kclManager.ast))
const varDecIndex = sketchPathToNode[1][0]
@ -206,7 +209,11 @@ export const ModelingMachineProvider = ({
onDrag: () => {},
})
},
'animate-to-face': async (_, { data: { plane, normal } }) => {
'animate-to-face': async ({
event: {
data: { plane, normal },
},
}) => {
const { modifiedAst, pathToNode } = startSketchOnDefault(
kclManager.ast,
plane
@ -220,8 +227,7 @@ export const ModelingMachineProvider = ({
}
},
'animate-to-sketch': async ({
sketchPathToNode,
sketchNormalBackUp,
context: { sketchPathToNode, sketchNormalBackUp },
}) => {
const quaternion = getSketchQuaternion(
sketchPathToNode || [],
@ -230,7 +236,7 @@ export const ModelingMachineProvider = ({
await sceneInfra.tweenCameraToQuaternion(quaternion)
},
'Get horizontal info': async ({
selectionRanges,
context: { selectionRanges },
}): Promise<SetSelections> => {
const { modifiedAst, pathToNodeMap } =
await applyConstraintHorzVertDistance({
@ -248,7 +254,7 @@ export const ModelingMachineProvider = ({
}
},
'Get vertical info': async ({
selectionRanges,
context: { selectionRanges },
}): Promise<SetSelections> => {
const { modifiedAst, pathToNodeMap } =
await applyConstraintHorzVertDistance({
@ -266,7 +272,7 @@ export const ModelingMachineProvider = ({
}
},
'Get angle info': async ({
selectionRanges,
context: { selectionRanges },
}): Promise<SetSelections> => {
const { modifiedAst, pathToNodeMap } = await (angleBetweenInfo({
selectionRanges,
@ -289,7 +295,7 @@ export const ModelingMachineProvider = ({
}
},
'Get length info': async ({
selectionRanges,
context: { selectionRanges },
}): Promise<SetSelections> => {
const { modifiedAst, pathToNodeMap } =
await applyConstraintAngleLength({ selectionRanges })
@ -304,7 +310,7 @@ export const ModelingMachineProvider = ({
}
},
'Get perpendicular distance info': async ({
selectionRanges,
context: { selectionRanges },
}): Promise<SetSelections> => {
const { modifiedAst, pathToNodeMap } = await applyConstraintIntersect(
{
@ -322,7 +328,7 @@ export const ModelingMachineProvider = ({
}
},
'Get ABS X info': async ({
selectionRanges,
context: { selectionRanges },
}): Promise<SetSelections> => {
const { modifiedAst, pathToNodeMap } =
await applyConstraintAbsDistance({
@ -340,7 +346,7 @@ export const ModelingMachineProvider = ({
}
},
'Get ABS Y info': async ({
selectionRanges,
context: { selectionRanges },
}): Promise<SetSelections> => {
const { modifiedAst, pathToNodeMap } =
await applyConstraintAbsDistance({
@ -358,7 +364,8 @@ export const ModelingMachineProvider = ({
}
},
},
devTools: true,
// TODO replace with inspect https://stately.ai/docs/inspector
// devTools: true,
}
)

View File

@ -81,7 +81,7 @@ export const authMachine = createMachine<UserContext, Events>(
'Log in': {
target: 'checkIfLoggedIn',
actions: assign({
token: (_, event) => {
token: ({ event }) => {
const token = event.token || ''
localStorage.setItem(TOKEN_PERSIST_KEY, token)
return token
@ -91,8 +91,7 @@ export const authMachine = createMachine<UserContext, Events>(
},
},
},
schema: { events: {} as { type: 'Log out' } | { type: 'Log in' } },
predictableActionArguments: true,
types: { events: {} as { type: 'Log out' } | { type: 'Log in' } },
preserveActionOrder: true,
context: {
token: persistedToken,

View File

@ -43,14 +43,14 @@ export const commandBarMachine = createMachine(
actions: [
assign({
commands: (context, event) =>
commands: ({ context, event }) =>
[...context.commands, ...event.data.commands].sort(
sortCommands
),
}),
],
internal: true,
reenter: false,
},
'Remove commands': {
@ -58,7 +58,7 @@ export const commandBarMachine = createMachine(
actions: [
assign({
commands: (context, event) =>
commands: ({ context, event }) =>
context.commands.filter(
(c) =>
!event.data.commands.some(
@ -70,7 +70,7 @@ export const commandBarMachine = createMachine(
}),
],
internal: true,
reenter: false,
},
},
},
@ -88,7 +88,7 @@ export const commandBarMachine = createMachine(
always: [
{
target: 'Closed',
cond: 'Command has no arguments',
guard: 'Command has no arguments',
actions: ['Execute command'],
},
{
@ -116,7 +116,7 @@ export const commandBarMachine = createMachine(
target: '#Command Bar.Checking Arguments',
actions: [
assign({
argumentsToSubmit: (context, event) => {
argumentsToSubmit: ({ context, event }) => {
const [argName, argData] = Object.entries(event.data)[0]
const { currentArgument } = context
if (!currentArgument) return {}
@ -142,7 +142,7 @@ export const commandBarMachine = createMachine(
on: {
'Change current argument': {
target: 'Gathering arguments',
internal: true,
reenter: false,
actions: ['Set current argument'],
},
@ -174,7 +174,7 @@ export const commandBarMachine = createMachine(
target: 'Review',
actions: [
assign({
argumentsToSubmit: (context, event) => {
argumentsToSubmit: ({ context, event }) => {
const argName = Object.keys(event.data)[0]
const { argumentsToSubmit } = context
const newArgumentsToSubmit = { ...argumentsToSubmit }
@ -199,7 +199,7 @@ export const commandBarMachine = createMachine(
onDone: [
{
target: 'Review',
cond: 'Command needs review',
guard: 'Command needs review',
},
{
target: 'Closed',
@ -222,11 +222,11 @@ export const commandBarMachine = createMachine(
Clear: {
target: '#Command Bar',
internal: true,
reenter: false,
actions: ['Clear argument data'],
},
},
schema: {
types: {
events: {} as
| { type: 'Open' }
| { type: 'Close' }
@ -275,7 +275,6 @@ export const commandBarMachine = createMachine(
data: { arg: CommandArgumentWithName<unknown> }
},
},
predictableActionArguments: true,
preserveActionOrder: true,
},
{

View File

@ -143,7 +143,7 @@ export const fileMachine = createMachine(
},
},
schema: {
types: {
events: {} as
| { type: 'Open file'; data: { name: string } }
| {
@ -161,7 +161,6 @@ export const fileMachine = createMachine(
| { type: 'assign'; data: { [key: string]: any } },
},
predictableActionArguments: true,
preserveActionOrder: true,
tsTypes: {} as import('./fileMachine.typegen').Typegen0,
},

View File

@ -136,7 +136,7 @@ export const homeMachine = createMachine(
},
},
schema: {
types: {
events: {} as
| { type: 'Open project'; data: HomeCommandSchema['Open project'] }
| { type: 'Rename project'; data: HomeCommandSchema['Rename project'] }
@ -150,7 +150,6 @@ export const homeMachine = createMachine(
| { type: 'assign'; data: { [key: string]: any } },
},
predictableActionArguments: true,
preserveActionOrder: true,
tsTypes: {} as import('./homeMachine.typegen').Typegen0,
},

View File

@ -123,7 +123,6 @@ export const modelingMachine = createMachine(
id: 'Modeling',
tsTypes: {} as import('./modelingMachine.typegen').Typegen0,
predictableActionArguments: true,
preserveActionOrder: true,
context: {
@ -142,7 +141,7 @@ export const modelingMachine = createMachine(
moveDescs: [] as MoveDesc[],
},
schema: {
types: {
events: {} as ModelingMachineEvent,
},
@ -151,14 +150,14 @@ export const modelingMachine = createMachine(
on: {
'Set selection': {
target: 'idle',
internal: true,
reenter: false,
actions: 'Set selection',
},
'Enter sketch': [
{
target: 'animating to existing sketch',
cond: 'Selection is on face',
guard: 'Selection is on face',
actions: ['set sketch metadata'],
},
'Sketch no face',
@ -166,9 +165,9 @@ export const modelingMachine = createMachine(
Extrude: {
target: 'idle',
cond: 'has valid extrude selection',
guard: 'has valid extrude selection',
actions: ['AST extrude'],
internal: true,
reenter: false,
},
},
@ -181,111 +180,111 @@ export const modelingMachine = createMachine(
on: {
'Set selection': {
target: 'SketchIdle',
internal: true,
reenter: false,
actions: 'Set selection',
},
'Make segment vertical': {
cond: 'Can make selection vertical',
guard: 'Can make selection vertical',
target: 'SketchIdle',
internal: true,
reenter: false,
actions: ['Make selection vertical'],
},
'Make segment horizontal': {
target: 'SketchIdle',
internal: true,
cond: 'Can make selection horizontal',
reenter: false,
guard: 'Can make selection horizontal',
actions: ['Make selection horizontal'],
},
'Constrain horizontal distance': {
target: 'Await horizontal distance info',
cond: 'Can constrain horizontal distance',
guard: 'Can constrain horizontal distance',
},
'Constrain vertical distance': {
target: 'Await vertical distance info',
cond: 'Can constrain vertical distance',
guard: 'Can constrain vertical distance',
},
'Constrain ABS X': {
target: 'Await ABS X info',
cond: 'Can constrain ABS X',
guard: 'Can constrain ABS X',
},
'Constrain ABS Y': {
target: 'Await ABS Y info',
cond: 'Can constrain ABS Y',
guard: 'Can constrain ABS Y',
},
'Constrain angle': {
target: 'Await angle info',
cond: 'Can constrain angle',
guard: 'Can constrain angle',
},
'Constrain length': {
target: 'Await length info',
cond: 'Can constrain length',
guard: 'Can constrain length',
},
'Constrain perpendicular distance': {
target: 'Await perpendicular distance info',
cond: 'Can constrain perpendicular distance',
guard: 'Can constrain perpendicular distance',
},
'Constrain horizontally align': {
cond: 'Can constrain horizontally align',
guard: 'Can constrain horizontally align',
target: 'SketchIdle',
internal: true,
reenter: false,
actions: ['Constrain horizontally align'],
},
'Constrain vertically align': {
cond: 'Can constrain vertically align',
guard: 'Can constrain vertically align',
target: 'SketchIdle',
internal: true,
reenter: false,
actions: ['Constrain vertically align'],
},
'Constrain snap to X': {
cond: 'Can constrain snap to X',
guard: 'Can constrain snap to X',
target: 'SketchIdle',
internal: true,
reenter: false,
actions: ['Constrain snap to X'],
},
'Constrain snap to Y': {
cond: 'Can constrain snap to Y',
guard: 'Can constrain snap to Y',
target: 'SketchIdle',
internal: true,
reenter: false,
actions: ['Constrain snap to Y'],
},
'Constrain equal length': {
cond: 'Can constrain equal length',
guard: 'Can constrain equal length',
target: 'SketchIdle',
internal: true,
reenter: false,
actions: ['Constrain equal length'],
},
'Constrain parallel': {
target: 'SketchIdle',
internal: true,
cond: 'Can canstrain parallel',
reenter: false,
guard: 'Can canstrain parallel',
actions: ['Constrain parallel'],
},
'Constrain remove constraints': {
target: 'SketchIdle',
internal: true,
cond: 'Can constrain remove constraints',
reenter: false,
guard: 'Can constrain remove constraints',
actions: ['Constrain remove constraints'],
},
'Re-execute': {
target: 'SketchIdle',
internal: true,
reenter: false,
actions: ['set sketchMetadata from pathToNode'],
},
@ -293,7 +292,7 @@ export const modelingMachine = createMachine(
'Equip tangential arc to': {
target: 'Tangential arc to',
cond: 'is editing existing sketch',
guard: 'is editing existing sketch',
},
},
@ -394,12 +393,12 @@ export const modelingMachine = createMachine(
'Set selection': {
target: 'Line tool',
description: `This is just here to stop one of the higher level "Set selections" firing when we are just trying to set the IDE code without triggering a full engine-execute`,
internal: true,
reenter: false,
},
'Equip tangential arc to': {
target: 'Tangential arc to',
cond: 'is editing existing sketch',
guard: 'is editing existing sketch',
},
},
@ -408,7 +407,7 @@ export const modelingMachine = createMachine(
always: [
{
target: 'normal',
cond: 'is editing existing sketch',
guard: 'is editing existing sketch',
actions: 'set up draft line',
},
'No Points',
@ -419,7 +418,7 @@ export const modelingMachine = createMachine(
on: {
'Set selection': {
target: 'normal',
internal: true,
reenter: false,
},
},
},
@ -445,7 +444,7 @@ export const modelingMachine = createMachine(
always: [
{
target: 'SketchIdle',
cond: 'is editing existing sketch',
guard: 'is editing existing sketch',
},
'Line tool',
],
@ -457,7 +456,7 @@ export const modelingMachine = createMachine(
on: {
'Set selection': {
target: 'Tangential arc to',
internal: true,
reenter: false,
},
'Equip Line tool': 'Line tool',
@ -514,7 +513,7 @@ export const modelingMachine = createMachine(
on: {
'Set selection': {
target: 'animating to plane',
internal: true,
reenter: false,
},
},
},
@ -542,14 +541,14 @@ export const modelingMachine = createMachine(
'Set selection': {
target: '#Modeling',
internal: true,
reenter: false,
actions: 'Set selection',
},
},
},
{
guards: {
'is editing existing sketch': ({ sketchPathToNode }) => {
'is editing existing sketch': ({ context: { sketchPathToNode } }) => {
// should check that the variable declaration is a pipeExpression
// and that the pipeExpression contains a "startProfileAt" callExpression
if (!sketchPathToNode) return false
@ -568,50 +567,53 @@ export const modelingMachine = createMachine(
)
return hasStartProfileAt && pipeExpression.body.length > 2
},
'Can make selection horizontal': ({ selectionRanges }) =>
'Can make selection horizontal': ({ context: { selectionRanges } }) =>
horzVertInfo(selectionRanges, 'horizontal').enabled,
'Can make selection vertical': ({ selectionRanges }) =>
'Can make selection vertical': ({ context: { selectionRanges } }) =>
horzVertInfo(selectionRanges, 'vertical').enabled,
'Can constrain horizontal distance': ({ selectionRanges }) =>
'Can constrain horizontal distance': ({ context: { selectionRanges } }) =>
horzVertDistanceInfo({ selectionRanges, constraint: 'setHorzDistance' })
.enabled,
'Can constrain vertical distance': ({ selectionRanges }) =>
'Can constrain vertical distance': ({ context: { selectionRanges } }) =>
horzVertDistanceInfo({ selectionRanges, constraint: 'setVertDistance' })
.enabled,
'Can constrain ABS X': ({ selectionRanges }) =>
'Can constrain ABS X': ({ context: { selectionRanges } }) =>
absDistanceInfo({ selectionRanges, constraint: 'xAbs' }).enabled,
'Can constrain ABS Y': ({ selectionRanges }) =>
'Can constrain ABS Y': ({ context: { selectionRanges } }) =>
absDistanceInfo({ selectionRanges, constraint: 'yAbs' }).enabled,
'Can constrain angle': ({ selectionRanges }) =>
'Can constrain angle': ({ context: { selectionRanges } }) =>
angleBetweenInfo({ selectionRanges }).enabled ||
angleLengthInfo({ selectionRanges, angleOrLength: 'setAngle' }).enabled,
'Can constrain length': ({ selectionRanges }) =>
'Can constrain length': ({ context: { selectionRanges } }) =>
angleLengthInfo({ selectionRanges }).enabled,
'Can constrain perpendicular distance': ({ selectionRanges }) =>
intersectInfo({ selectionRanges }).enabled,
'Can constrain horizontally align': ({ selectionRanges }) =>
'Can constrain perpendicular distance': ({
context: { selectionRanges },
}) => intersectInfo({ selectionRanges }).enabled,
'Can constrain horizontally align': ({ context: { selectionRanges } }) =>
horzVertDistanceInfo({ selectionRanges, constraint: 'setHorzDistance' })
.enabled,
'Can constrain vertically align': ({ selectionRanges }) =>
'Can constrain vertically align': ({ context: { selectionRanges } }) =>
horzVertDistanceInfo({ selectionRanges, constraint: 'setHorzDistance' })
.enabled,
'Can constrain snap to X': ({ selectionRanges }) =>
'Can constrain snap to X': ({ context: { selectionRanges } }) =>
absDistanceInfo({ selectionRanges, constraint: 'snapToXAxis' }).enabled,
'Can constrain snap to Y': ({ selectionRanges }) =>
'Can constrain snap to Y': ({ context: { selectionRanges } }) =>
absDistanceInfo({ selectionRanges, constraint: 'snapToYAxis' }).enabled,
'Can constrain equal length': ({ selectionRanges }) =>
'Can constrain equal length': ({ context: { selectionRanges } }) =>
setEqualLengthInfo({ selectionRanges }).enabled,
'Can canstrain parallel': ({ selectionRanges }) =>
'Can canstrain parallel': ({ context: { selectionRanges } }) =>
equalAngleInfo({ selectionRanges }).enabled,
'Can constrain remove constraints': ({ selectionRanges }) =>
'Can constrain remove constraints': ({ context: { selectionRanges } }) =>
removeConstrainingValuesInfo({ selectionRanges }).enabled,
},
// end guards
actions: {
'set sketchMetadata from pathToNode': assign(({ sketchPathToNode }) => {
'set sketchMetadata from pathToNode': assign(
({ context: { sketchPathToNode } }) => {
if (!sketchPathToNode) return {}
return getSketchMetadataFromPathToNode(sketchPathToNode)
}),
}
),
'hide default planes': () => {
sceneInfra.removeDefaultPlanes()
kclManager.hidePlanes()
@ -621,7 +623,7 @@ export const modelingMachine = createMachine(
sketchEnginePathId: '',
sketchPlaneId: '',
}),
'set sketch metadata': assign(({ selectionRanges }) => {
'set sketch metadata': assign(({ context: { selectionRanges } }) => {
const sourceRange = selectionRanges.codeBasedSelections[0].range
const sketchPathToNode = getNodePathFromSourceRange(
kclManager.ast,
@ -632,10 +634,12 @@ export const modelingMachine = createMachine(
selectionRanges
)
}),
'set new sketch metadata': assign((_, { data }) => data),
'set new sketch metadata': assign(({ event: { data } }) => data),
// TODO implement source ranges for all of these constraints
// need to make the async like the modal constraints
'Make selection horizontal': ({ selectionRanges, sketchPathToNode }) => {
'Make selection horizontal': ({
context: { selectionRanges, sketchPathToNode },
}) => {
const { modifiedAst } = applyConstraintHorzVert(
selectionRanges,
'horizontal',
@ -647,7 +651,9 @@ export const modelingMachine = createMachine(
modifiedAst
)
},
'Make selection vertical': ({ selectionRanges, sketchPathToNode }) => {
'Make selection vertical': ({
context: { selectionRanges, sketchPathToNode },
}) => {
const { modifiedAst } = applyConstraintHorzVert(
selectionRanges,
'vertical',
@ -660,8 +666,7 @@ export const modelingMachine = createMachine(
)
},
'Constrain horizontally align': ({
selectionRanges,
sketchPathToNode,
context: { selectionRanges, sketchPathToNode },
}) => {
const { modifiedAst } = applyConstraintHorzVertAlign({
selectionRanges,
@ -672,7 +677,9 @@ export const modelingMachine = createMachine(
modifiedAst
)
},
'Constrain vertically align': ({ selectionRanges, sketchPathToNode }) => {
'Constrain vertically align': ({
context: { selectionRanges, sketchPathToNode },
}) => {
const { modifiedAst } = applyConstraintHorzVertAlign({
selectionRanges,
constraint: 'setHorzDistance',
@ -682,7 +689,9 @@ export const modelingMachine = createMachine(
modifiedAst
)
},
'Constrain snap to X': ({ selectionRanges, sketchPathToNode }) => {
'Constrain snap to X': ({
context: { selectionRanges, sketchPathToNode },
}) => {
const { modifiedAst } = applyConstraintAxisAlign({
selectionRanges,
constraint: 'snapToXAxis',
@ -692,7 +701,9 @@ export const modelingMachine = createMachine(
modifiedAst
)
},
'Constrain snap to Y': ({ selectionRanges, sketchPathToNode }) => {
'Constrain snap to Y': ({
context: { selectionRanges, sketchPathToNode },
}) => {
const { modifiedAst } = applyConstraintAxisAlign({
selectionRanges,
constraint: 'snapToYAxis',
@ -702,7 +713,9 @@ export const modelingMachine = createMachine(
modifiedAst
)
},
'Constrain equal length': ({ selectionRanges, sketchPathToNode }) => {
'Constrain equal length': ({
context: { selectionRanges, sketchPathToNode },
}) => {
const { modifiedAst } = applyConstraintEqualLength({
selectionRanges,
})
@ -711,7 +724,9 @@ export const modelingMachine = createMachine(
modifiedAst
)
},
'Constrain parallel': ({ selectionRanges, sketchPathToNode }) => {
'Constrain parallel': ({
context: { selectionRanges, sketchPathToNode },
}) => {
const { modifiedAst } = applyConstraintEqualAngle({
selectionRanges,
})
@ -721,8 +736,7 @@ export const modelingMachine = createMachine(
)
},
'Constrain remove constraints': ({
selectionRanges,
sketchPathToNode,
context: { selectionRanges, sketchPathToNode },
}) => {
const { modifiedAst } = applyRemoveConstrainingValues({
selectionRanges,
@ -732,7 +746,7 @@ export const modelingMachine = createMachine(
modifiedAst
)
},
'AST extrude': (_, event) => {
'AST extrude': ({ event }) => {
if (!event.data) return
const { selection, distance } = event.data
const pathToNode = getNodePathFromSourceRange(
@ -750,12 +764,15 @@ export const modelingMachine = createMachine(
focusPath: pathToExtrudeArg,
})
},
'conditionally equip line tool': (_, { type }) => {
'conditionally equip line tool': ({ event: { type } }) => {
if (type === 'done.invoke.animate-to-face') {
sceneInfra.modelingSend('Equip Line tool')
}
},
'setup client side sketch segments': ({ sketchPathToNode }, { type }) => {
'setup client side sketch segments': ({
context: { sketchPathToNode },
event: { type },
}) => {
if (Object.keys(sceneEntitiesManager.activeSegments).length > 0) {
sceneEntitiesManager
.tearDownSketch({ removeAxis: false })
@ -779,13 +796,15 @@ export const modelingMachine = createMachine(
}
},
'remove sketch grid': () => sceneEntitiesManager.removeSketchGrid(),
'set up draft line': ({ sketchPathToNode }) => {
'set up draft line': ({ context: { sketchPathToNode } }) => {
sceneEntitiesManager.setUpDraftLine(sketchPathToNode || [])
},
'set up draft arc': ({ sketchPathToNode }) => {
'set up draft arc': ({ context: { sketchPathToNode } }) => {
sceneEntitiesManager.setUpDraftArc(sketchPathToNode || [])
},
'set up draft line without teardown': ({ sketchPathToNode }) =>
'set up draft line without teardown': ({
context: { sketchPathToNode },
}) =>
sceneEntitiesManager.setupSketch({
sketchPathToNode: sketchPathToNode || [],
draftSegment: 'line',
@ -795,7 +814,9 @@ export const modelingMachine = createMachine(
sceneEntitiesManager.setupDefaultPlaneHover()
kclManager.showPlanes()
},
'setup noPoints onClick listener': ({ sketchPathToNode }) => {
'setup noPoints onClick listener': ({
context: { sketchPathToNode },
}) => {
sceneEntitiesManager.createIntersectionPlane()
const sketchGroup = sketchGroupFromPathToNode({
pathToNode: sketchPathToNode || [],
@ -824,7 +845,7 @@ export const modelingMachine = createMachine(
},
})
},
'add axis n grid': ({ sketchPathToNode }) =>
'add axis n grid': ({ context: { sketchPathToNode } }) =>
sceneEntitiesManager.createSketchAxis(sketchPathToNode || []),
'reset client scene mouse handlers': () => {
// when not in sketch mode we don't need any mouse listeners

View File

@ -27,7 +27,6 @@ export const settingsMachine = createMachine(
{
/** @xstate-layout N4IgpgJg5mDOIC5QGUwBc0EsB2VYDpMIAbMAYlTQAIAVACzAFswBtABgF1FQAHAe1iYsfbNxAAPRAA42+AEwB2KQFYAzGznKAnADZli1QBoQAT2kBGKfm37lOned3nzqgL6vjlLLgJFSFdCoAETAAMwBDAFdiagAFACc+ACswAGNqADlw5nYuJBB+QWFRfMkEABY5fDYa2rra83LjMwQdLWV8BXLyuxlVLU1Ld090bzxCEnJKYLComODMeLS0PniTXLFCoUwRMTK7fC1zNql7NgUjtnKjU0RlBSqpLVUVPVUda60tYZAvHHG-FNAgBVbBCKjIEywNBMDb5LbFPaILqdfRSORsS4qcxXZqIHqyK6qY4XOxsGTKco-P4+Cb+aYAIXCsDAVFBQjhvAE212pWkskUKnUml0+gUNxaqkU+EccnKF1UCnucnMcjcHl+o3+vkmZBofCgUFIMwARpEoFRYuFsGBiJyCtzEXzWrJlGxlKdVFKvfY1XiEBjyvhVOVzBdzu13pYFNStbTAQFqAB5bAmvjheIQf4QtDhNCRWD2hE7EqgfayHTEh7lHQNSxSf1Scz4cpHHFyFVujTKczuDXYPgQOBiGl4TaOktIhAAWg6X3nC4Xp39050sYw2rpYHHRUnztVhPJqmUlIGbEriv9WhrLZ6uibHcqUr7riAA */
id: 'Settings',
predictableActionArguments: true,
context: {
baseUnit: 'in' as BaseUnit,
cameraControls: 'KittyCAD' as CameraSystem,
@ -47,7 +46,7 @@ export const settingsMachine = createMachine(
'Set Base Unit': {
actions: [
assign({
baseUnit: (_, event) => {
baseUnit: ({ event }) => {
console.log('event', event)
return event.data.baseUnit
},
@ -56,92 +55,92 @@ export const settingsMachine = createMachine(
'toastSuccess',
],
target: 'idle',
internal: true,
reenter: false,
},
'Set Camera Controls': {
actions: [
assign({
cameraControls: (_, event) => event.data.cameraControls,
cameraControls: ({ event }) => event.data.cameraControls,
}),
'persistSettings',
'toastSuccess',
],
target: 'idle',
internal: true,
reenter: false,
},
'Set Default Directory': {
actions: [
assign({
defaultDirectory: (_, event) => event.data.defaultDirectory,
defaultDirectory: ({ event }) => event.data.defaultDirectory,
}),
'persistSettings',
'toastSuccess',
],
target: 'idle',
internal: true,
reenter: false,
},
'Set Default Project Name': {
actions: [
assign({
defaultProjectName: (_, event) =>
defaultProjectName: ({ event }) =>
event.data.defaultProjectName.trim() || DEFAULT_PROJECT_NAME,
}),
'persistSettings',
'toastSuccess',
],
target: 'idle',
internal: true,
reenter: false,
},
'Set Onboarding Status': {
actions: [
assign({
onboardingStatus: (_, event) => event.data.onboardingStatus,
onboardingStatus: ({ event }) => event.data.onboardingStatus,
}),
'persistSettings',
],
target: 'idle',
internal: true,
reenter: false,
},
'Set Text Wrapping': {
actions: [
assign({
textWrapping: (_, event) => event.data.textWrapping,
textWrapping: ({ event }) => event.data.textWrapping,
}),
'persistSettings',
'toastSuccess',
],
target: 'idle',
internal: true,
reenter: false,
},
'Set Theme': {
actions: [
assign({
theme: (_, event) => event.data.theme,
theme: ({ event }) => event.data.theme,
}),
'persistSettings',
'toastSuccess',
'setThemeClass',
],
target: 'idle',
internal: true,
reenter: false,
},
'Set Unit System': {
actions: [
assign({
unitSystem: (_, event) => event.data.unitSystem,
baseUnit: (_, event) =>
unitSystem: ({ event }) => event.data.unitSystem,
baseUnit: ({ event }) =>
event.data.unitSystem === 'imperial' ? 'in' : 'mm',
}),
'persistSettings',
'toastSuccess',
],
target: 'idle',
internal: true,
reenter: false,
},
'Toggle Debug Panel': {
actions: [
assign({
showDebugPanel: (context) => {
showDebugPanel: ({ context }) => {
return !context.showDebugPanel
},
}),
@ -149,13 +148,13 @@ export const settingsMachine = createMachine(
'toastSuccess',
],
target: 'idle',
internal: true,
reenter: false,
},
},
},
},
tsTypes: {} as import('./settingsMachine.typegen').Typegen0,
schema: {
types: {
events: {} as
| { type: 'Set Base Unit'; data: { baseUnit: BaseUnit } }
| {
@ -186,7 +185,7 @@ export const settingsMachine = createMachine(
console.error(e)
}
},
setThemeClass: (context, event) => {
setThemeClass: ({ context, event }) => {
const currentTheme =
event.type === 'Set Theme' ? event.data.theme : context.theme
setThemeClass(

View File

@ -1,5 +1,6 @@
{
"compilerOptions": {
"strictNullChecks": true,
"baseUrl": "src",
"paths": {
"/*": ["src/*"]

View File

@ -2887,10 +2887,10 @@
"@babel/types" "^7.21.4"
recast "^0.23.1"
"@xstate/react@^3.2.2":
version "3.2.2"
resolved "https://registry.yarnpkg.com/@xstate/react/-/react-3.2.2.tgz#ddf0f9d75e2c19375b1e1b7335e72cb99762aed8"
integrity sha512-feghXWLedyq8JeL13yda3XnHPZKwYDN5HPBLykpLeuNpr9178tQd2/3d0NrH6gSd0sG5mLuLeuD+ck830fgzLQ==
"@xstate/react@^4.1.0":
version "4.1.0"
resolved "https://registry.yarnpkg.com/@xstate/react/-/react-4.1.0.tgz#369378951e1f7f9326700f65ed02847598aad704"
integrity sha512-Fh89luCwuMXIVXIua67d8pNuVgdGpqke2jHfIIL+ZjkfNh6YFtPDSwNSZZDhdNUsOW1zZYSbtUzbC8MIUyTSHQ==
dependencies:
use-isomorphic-layout-effect "^1.1.2"
use-sync-external-store "^1.0.0"
@ -8992,11 +8992,16 @@ ws@^8.8.0:
resolved "https://registry.yarnpkg.com/xstate/-/xstate-5.0.0-beta.54.tgz#d80f1a9e43ad883a65fc9b399161bd39633bd9bf"
integrity sha512-BTnCPBQ2iTKe4uCnHEe1hNx6VTbXU+5mQGybSQHOjTLiBi4Ryi+tL9T6N1tmqagvM8rfl4XRfvndogfWCWcdpw==
xstate@^4.33.4, xstate@^4.38.2:
xstate@^4.33.4:
version "4.38.3"
resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.38.3.tgz#4e15e7ad3aa0ca1eea2010548a5379966d8f1075"
integrity sha512-SH7nAaaPQx57dx6qvfcIgqKRXIh4L0A1iYEqim4s1u7c9VoCgzZc+63FY90AKU4ZzOC2cfJzTnpO4zK7fCUzzw==
xstate@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/xstate/-/xstate-5.7.1.tgz#c9d6af13c01e223437b53648be59b55f85f43288"
integrity sha512-x1fa1X/K2bCdXrN6Hrll30Q00iprXaaPqB0U3N4nUgjngTNxQbnBvAQ4WSH6ctdU3jbH32+S3GDYctM5K7t8Vw==
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"