From 7cd39be3bcc5b67a4404cc10ec589b36fdb35f7c Mon Sep 17 00:00:00 2001 From: Sean Martin Date: Fri, 26 Jun 2026 17:03:16 +0200 Subject: [PATCH 1/2] refactor: update command naming --- .../catmaid/spatial_skeleton_commands.ts | 14 ++++------ src/layer/segmentation/index.spec.ts | 2 +- src/layer/segmentation/index.ts | 28 +++++++++---------- src/skeleton/command_factories.ts | 4 +-- src/skeleton/command_history.spec.ts | 6 ++-- src/skeleton/command_history.ts | 12 +------- .../{actions.ts => command_protocol.ts} | 26 +++++++++++++++++ ...eton_commands.spec.ts => commands.spec.ts} | 14 +++++----- ...atial_skeleton_commands.ts => commands.ts} | 10 +++---- src/skeleton/spatial_skeleton_manager.spec.ts | 2 +- src/skeleton/spatial_skeleton_manager.ts | 2 +- src/ui/skeleton_edit_tools.spec.ts | 8 +++--- src/ui/skeleton_edit_tools.ts | 18 ++++++------ src/ui/skeleton_tab.ts | 18 ++++++------ 14 files changed, 88 insertions(+), 76 deletions(-) rename src/skeleton/{actions.ts => command_protocol.ts} (72%) rename src/skeleton/{spatial_skeleton_commands.spec.ts => commands.spec.ts} (99%) rename src/skeleton/{spatial_skeleton_commands.ts => commands.ts} (98%) diff --git a/src/datasource/catmaid/spatial_skeleton_commands.ts b/src/datasource/catmaid/spatial_skeleton_commands.ts index 367762a09d..7df290bc71 100644 --- a/src/datasource/catmaid/spatial_skeleton_commands.ts +++ b/src/datasource/catmaid/spatial_skeleton_commands.ts @@ -52,20 +52,18 @@ import { addSegmentToVisibleSets, removeSegmentFromVisibleSets, } from "#src/segmentation_display_state/base.js"; -import { - SpatialSkeletonActions, - type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; import type { SpatiallyIndexedSkeletonNode, SpatialSkeletonSourceState, SpatialSkeletonVector, } from "#src/skeleton/api.js"; import type { SpatialSkeletonEditCommandFactory } from "#src/skeleton/command_factories.js"; -import type { - SpatialSkeletonCommand, - SpatialSkeletonCommandContext, -} from "#src/skeleton/command_history.js"; +import { + SpatialSkeletonActions, + type SpatialSkeletonAction, + type SpatialSkeletonCommand, + type SpatialSkeletonCommandContext, +} from "#src/skeleton/command_protocol.js"; import type { SpatiallyIndexedSkeletonLayer } from "#src/skeleton/frontend.js"; import { findSpatiallyIndexedSkeletonNode, diff --git a/src/layer/segmentation/index.spec.ts b/src/layer/segmentation/index.spec.ts index a0066483d7..eb835e8fd7 100644 --- a/src/layer/segmentation/index.spec.ts +++ b/src/layer/segmentation/index.spec.ts @@ -17,7 +17,7 @@ import { describe, expect, it, vi } from "vitest"; import type { RenderLayerTransform } from "#src/render_coordinate_transform.js"; -import { SpatialSkeletonActions } from "#src/skeleton/actions.js"; +import { SpatialSkeletonActions } from "#src/skeleton/command_protocol.js"; import { WatchableValue } from "#src/trackable_value.js"; if (!("WebGL2RenderingContext" in globalThis)) { diff --git a/src/layer/segmentation/index.ts b/src/layer/segmentation/index.ts index 5ef75d3f13..4cd9b41faf 100644 --- a/src/layer/segmentation/index.ts +++ b/src/layer/segmentation/index.ts @@ -95,17 +95,26 @@ import type { import { SegmentationGraphSourceTab } from "#src/segmentation_graph/source.js"; import { SharedDisjointUint64Sets } from "#src/shared_disjoint_sets.js"; import { SharedWatchableValue } from "#src/shared_watchable_value.js"; +import type { + SpatiallyIndexedSkeletonNode, + SpatialSkeletonSourceState, +} from "#src/skeleton/api.js"; import { DEFAULT_SPATIAL_SKELETON_EDIT_ACTIONS, getSpatialSkeletonActionSupportLabel, isSpatialSkeletonEditAction, SpatialSkeletonActions, type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; -import type { - SpatiallyIndexedSkeletonNode, - SpatialSkeletonSourceState, -} from "#src/skeleton/api.js"; +} from "#src/skeleton/command_protocol.js"; +import { + executeSpatialSkeletonDeleteNode, + executeSpatialSkeletonNodeConfidenceUpdate, + executeSpatialSkeletonNodeDescriptionUpdate, + executeSpatialSkeletonNodeRadiusUpdate, + executeSpatialSkeletonReroot, + executeSpatialSkeletonNodeTrueEndUpdate, + showSpatialSkeletonActionError, +} from "#src/skeleton/commands.js"; import { PerspectiveViewSkeletonLayer, SkeletonLayer, @@ -129,15 +138,6 @@ import { SpatialSkeletonDisplayNodeType, SpatialSkeletonNodeFilterType, } from "#src/skeleton/node_types.js"; -import { - executeSpatialSkeletonDeleteNode, - executeSpatialSkeletonNodeConfidenceUpdate, - executeSpatialSkeletonNodeDescriptionUpdate, - executeSpatialSkeletonNodeRadiusUpdate, - executeSpatialSkeletonReroot, - executeSpatialSkeletonNodeTrueEndUpdate, - showSpatialSkeletonActionError, -} from "#src/skeleton/spatial_skeleton_commands.js"; import { editableSpatiallyIndexedSkeletonSourceSupportsAction, getEditableSpatiallyIndexedSkeletonSource, diff --git a/src/skeleton/command_factories.ts b/src/skeleton/command_factories.ts index f889601bc0..5803a85a61 100644 --- a/src/skeleton/command_factories.ts +++ b/src/skeleton/command_factories.ts @@ -17,9 +17,9 @@ import type { SegmentationUserLayer } from "#src/layer/segmentation/index.js"; import { SpatialSkeletonActions, + type SpatialSkeletonCommand, type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; -import type { SpatialSkeletonCommand } from "#src/skeleton/command_history.js"; +} from "#src/skeleton/command_protocol.js"; export type SpatialSkeletonCommandPayload = object; diff --git a/src/skeleton/command_history.spec.ts b/src/skeleton/command_history.spec.ts index ef3d36aaaa..a7f2467d9e 100644 --- a/src/skeleton/command_history.spec.ts +++ b/src/skeleton/command_history.spec.ts @@ -16,10 +16,8 @@ import { describe, expect, it } from "vitest"; -import { - SpatialSkeletonCommandHistory, - type SpatialSkeletonCommand, -} from "#src/skeleton/command_history.js"; +import { SpatialSkeletonCommandHistory } from "#src/skeleton/command_history.js"; +import { type SpatialSkeletonCommand } from "#src/skeleton/command_protocol.js"; function deferred() { let resolve: (() => void) | undefined; diff --git a/src/skeleton/command_history.ts b/src/skeleton/command_history.ts index 4ca7093210..c81aa18013 100644 --- a/src/skeleton/command_history.ts +++ b/src/skeleton/command_history.ts @@ -14,22 +14,12 @@ * limitations under the License. */ +import type { SpatialSkeletonCommand } from "#src/skeleton/command_protocol.js"; import { WatchableValue } from "#src/trackable_value.js"; import { RefCounted } from "#src/util/disposable.js"; export const SPATIAL_SKELETON_COMMAND_HISTORY_MAX_ENTRIES = 100; -export interface SpatialSkeletonCommandContext { - readonly mappings: SpatialSkeletonCommandMappings; -} - -export interface SpatialSkeletonCommand { - readonly label: string; - execute(context: SpatialSkeletonCommandContext): Promise; - undo(context: SpatialSkeletonCommandContext): Promise; - redo?(context: SpatialSkeletonCommandContext): Promise; -} - interface SpatialSkeletonCommandMappingSnapshot { nodeIdMappings: Array<[number, number]>; segmentIdMappings: Array<[number, number]>; diff --git a/src/skeleton/actions.ts b/src/skeleton/command_protocol.ts similarity index 72% rename from src/skeleton/actions.ts rename to src/skeleton/command_protocol.ts index 283cb7a7a7..77aaa775a0 100644 --- a/src/skeleton/actions.ts +++ b/src/skeleton/command_protocol.ts @@ -72,3 +72,29 @@ export function getSpatialSkeletonActionSupportLabel( return "skeleton splitting"; } } + +export interface SpatialSkeletonCommandContext { + readonly mappings: { + resolveNodeId(nodeId: number | undefined): number | undefined; + resolveSegmentId(segmentId: number | undefined): number | undefined; + getStableNodeId(nodeId: number | undefined): number | undefined; + getStableSegmentId(segmentId: number | undefined): number | undefined; + getStableOrCurrentNodeId(nodeId: number | undefined): number | undefined; + getStableOrCurrentSegmentId(segmentId: number | undefined): number | undefined; + remapNodeId( + originalNodeId: number | undefined, + currentNodeId: number, + ): boolean; + remapSegmentId( + originalSegmentId: number | undefined, + currentSegmentId: number, + ): boolean; + }; +} + +export interface SpatialSkeletonCommand { + readonly label: string; + execute(context: SpatialSkeletonCommandContext): Promise; + undo(context: SpatialSkeletonCommandContext): Promise; + redo?(context: SpatialSkeletonCommandContext): Promise; +} diff --git a/src/skeleton/spatial_skeleton_commands.spec.ts b/src/skeleton/commands.spec.ts similarity index 99% rename from src/skeleton/spatial_skeleton_commands.spec.ts rename to src/skeleton/commands.spec.ts index 26db38d875..9987713a12 100644 --- a/src/skeleton/spatial_skeleton_commands.spec.ts +++ b/src/skeleton/commands.spec.ts @@ -19,14 +19,9 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { makeCatmaidNodeSourceState } from "#src/datasource/catmaid/api.js"; import { buildCatmaidNeighborhoodEditContext } from "#src/datasource/catmaid/edit_state.js"; import { CatmaidSpatialSkeletonEditCommands } from "#src/datasource/catmaid/spatial_skeleton_commands.js"; -import { SpatialSkeletonActions } from "#src/skeleton/actions.js"; import type { SpatiallyIndexedSkeletonNode } from "#src/skeleton/api.js"; import { SpatialSkeletonCommandHistory } from "#src/skeleton/command_history.js"; -import { - findSpatiallyIndexedSkeletonNode, - getSpatiallyIndexedSkeletonDirectChildren, - getSpatiallyIndexedSkeletonNodeParent, -} from "#src/skeleton/node_traversal.js"; +import { SpatialSkeletonActions } from "#src/skeleton/command_protocol.js"; import { executeSpatialSkeletonAddNode, executeSpatialSkeletonDeleteNode, @@ -41,7 +36,12 @@ import { executeSpatialSkeletonSplit, redoSpatialSkeletonCommand, undoSpatialSkeletonCommand, -} from "#src/skeleton/spatial_skeleton_commands.js"; +} from "#src/skeleton/commands.js"; +import { + findSpatiallyIndexedSkeletonNode, + getSpatiallyIndexedSkeletonDirectChildren, + getSpatiallyIndexedSkeletonNodeParent, +} from "#src/skeleton/node_traversal.js"; import { SpatialSkeletonState } from "#src/skeleton/spatial_skeleton_manager.js"; import { StatusMessage } from "#src/status.js"; diff --git a/src/skeleton/spatial_skeleton_commands.ts b/src/skeleton/commands.ts similarity index 98% rename from src/skeleton/spatial_skeleton_commands.ts rename to src/skeleton/commands.ts index 83731a5f09..cbd5671e4f 100644 --- a/src/skeleton/spatial_skeleton_commands.ts +++ b/src/skeleton/commands.ts @@ -14,10 +14,6 @@ * limitations under the License. */ -import { - SpatialSkeletonActions, - type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; import type { EditableSpatiallyIndexedSkeletonSource, SpatiallyIndexedSkeletonNode, @@ -26,7 +22,11 @@ import type { SpatialSkeletonCommandPayload, SpatialSkeletonEditCommandFactory, } from "#src/skeleton/command_factories.js"; -import type { SpatialSkeletonCommand } from "#src/skeleton/command_history.js"; +import { + SpatialSkeletonActions, + type SpatialSkeletonAction, + type SpatialSkeletonCommand, +} from "#src/skeleton/command_protocol.js"; import { getSpatialSkeletonActionErrorMessage } from "#src/skeleton/edit_errors.js"; import { getEditableSpatiallyIndexedSkeletonSource, diff --git a/src/skeleton/spatial_skeleton_manager.spec.ts b/src/skeleton/spatial_skeleton_manager.spec.ts index 64b7b4f54e..02fa70e9c9 100644 --- a/src/skeleton/spatial_skeleton_manager.spec.ts +++ b/src/skeleton/spatial_skeleton_manager.spec.ts @@ -16,7 +16,7 @@ import { describe, expect, it, vi } from "vitest"; -import { SpatialSkeletonActions } from "#src/skeleton/actions.js"; +import { SpatialSkeletonActions } from "#src/skeleton/command_protocol.js"; import { buildSpatiallyIndexedSkeletonNavigationGraph, getFlatListNodeIds, diff --git a/src/skeleton/spatial_skeleton_manager.ts b/src/skeleton/spatial_skeleton_manager.ts index d8d1c65389..ba39996136 100644 --- a/src/skeleton/spatial_skeleton_manager.ts +++ b/src/skeleton/spatial_skeleton_manager.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import type { SpatialSkeletonAction } from "#src/skeleton/actions.js"; import type { EditableSpatiallyIndexedSkeletonSource, SpatialSkeletonConfidenceConfiguration, @@ -29,6 +28,7 @@ import { SPATIAL_SKELETON_EDIT_COMMAND_METADATA, } from "#src/skeleton/command_factories.js"; import { SpatialSkeletonCommandHistory } from "#src/skeleton/command_history.js"; +import type { SpatialSkeletonAction } from "#src/skeleton/command_protocol.js"; import type { SpatiallyIndexedSkeletonLayer } from "#src/skeleton/frontend.js"; import { WatchableValue } from "#src/trackable_value.js"; import { RefCounted } from "#src/util/disposable.js"; diff --git a/src/ui/skeleton_edit_tools.spec.ts b/src/ui/skeleton_edit_tools.spec.ts index 698b9c0596..8689bef9ab 100644 --- a/src/ui/skeleton_edit_tools.spec.ts +++ b/src/ui/skeleton_edit_tools.spec.ts @@ -18,16 +18,16 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { makeCatmaidNodeSourceState } from "#src/datasource/catmaid/api.js"; import { CatmaidSpatialSkeletonEditCommands } from "#src/datasource/catmaid/spatial_skeleton_commands.js"; +import type { SpatiallyIndexedSkeletonNode } from "#src/skeleton/api.js"; +import { SpatialSkeletonCommandHistory } from "#src/skeleton/command_history.js"; import { SpatialSkeletonActions, type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; -import type { SpatiallyIndexedSkeletonNode } from "#src/skeleton/api.js"; -import { SpatialSkeletonCommandHistory } from "#src/skeleton/command_history.js"; +} from "#src/skeleton/command_protocol.js"; import { executeSpatialSkeletonAddNode, executeSpatialSkeletonMerge, -} from "#src/skeleton/spatial_skeleton_commands.js"; +} from "#src/skeleton/commands.js"; import { StatusMessage } from "#src/status.js"; if (!("WebGL2RenderingContext" in globalThis)) { diff --git a/src/ui/skeleton_edit_tools.ts b/src/ui/skeleton_edit_tools.ts index a0dbe861c8..fbd33049aa 100644 --- a/src/ui/skeleton_edit_tools.ts +++ b/src/ui/skeleton_edit_tools.ts @@ -24,11 +24,19 @@ import { import { getChunkPositionFromCombinedGlobalLocalPositions } from "#src/render_coordinate_transform.js"; import { RenderedDataPanel } from "#src/rendered_data_panel.js"; import { getVisibleSegments } from "#src/segmentation_display_state/base.js"; -import { SpatialSkeletonActions } from "#src/skeleton/actions.js"; import type { SpatialSkeletonSourceState, SpatialSkeletonVector, } from "#src/skeleton/api.js"; +import { SpatialSkeletonActions } from "#src/skeleton/command_protocol.js"; +import { + executeSpatialSkeletonAddNode, + executeSpatialSkeletonDeleteNode, + executeSpatialSkeletonMerge, + executeSpatialSkeletonMoveNode, + executeSpatialSkeletonSplit, + showSpatialSkeletonActionError, +} from "#src/skeleton/commands.js"; import { type SpatiallyIndexedSkeletonLayer, setSpatialSkeletonModesToLinesAndPoints, @@ -37,14 +45,6 @@ import { PerspectiveViewSpatiallyIndexedSkeletonLayer, SliceViewPanelSpatiallyIndexedSkeletonLayer, } from "#src/skeleton/frontend.js"; -import { - executeSpatialSkeletonAddNode, - executeSpatialSkeletonDeleteNode, - executeSpatialSkeletonMerge, - executeSpatialSkeletonMoveNode, - executeSpatialSkeletonSplit, - showSpatialSkeletonActionError, -} from "#src/skeleton/spatial_skeleton_commands.js"; import { StatusMessage } from "#src/status.js"; import type { SpatialSkeletonToolPointInfo } from "#src/ui/skeleton_edit_tool_messages.js"; import { diff --git a/src/ui/skeleton_tab.ts b/src/ui/skeleton_tab.ts index 7a49f32033..84988157fb 100644 --- a/src/ui/skeleton_tab.ts +++ b/src/ui/skeleton_tab.ts @@ -36,11 +36,18 @@ import { getVisibleSegments, } from "#src/segmentation_display_state/base.js"; import { getBaseObjectColor } from "#src/segmentation_display_state/frontend.js"; +import type { SpatiallyIndexedSkeletonNode } from "#src/skeleton/api.js"; import { SpatialSkeletonActions, type SpatialSkeletonAction, -} from "#src/skeleton/actions.js"; -import type { SpatiallyIndexedSkeletonNode } from "#src/skeleton/api.js"; +} from "#src/skeleton/command_protocol.js"; +import { + executeSpatialSkeletonDeleteNode, + executeSpatialSkeletonNodeTrueEndUpdate, + redoSpatialSkeletonCommand, + showSpatialSkeletonActionError, + undoSpatialSkeletonCommand, +} from "#src/skeleton/commands.js"; import { buildSpatiallyIndexedSkeletonNavigationGraph, getBranchEnd as getBranchEndFromGraph, @@ -60,13 +67,6 @@ import { SpatialSkeletonDisplayNodeType, SpatialSkeletonNodeFilterType, } from "#src/skeleton/node_types.js"; -import { - executeSpatialSkeletonDeleteNode, - executeSpatialSkeletonNodeTrueEndUpdate, - redoSpatialSkeletonCommand, - showSpatialSkeletonActionError, - undoSpatialSkeletonCommand, -} from "#src/skeleton/spatial_skeleton_commands.js"; import { StatusMessage } from "#src/status.js"; import { observeWatchable, registerNested } from "#src/trackable_value.js"; import { From bc8475846c5cbdedd492f4bbc253c4adf851b8e0 Mon Sep 17 00:00:00 2001 From: Sean Martin Date: Fri, 26 Jun 2026 17:09:05 +0200 Subject: [PATCH 2/2] chore: update func to async --- src/skeleton/commands.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/skeleton/commands.ts b/src/skeleton/commands.ts index cbd5671e4f..73798994ef 100644 --- a/src/skeleton/commands.ts +++ b/src/skeleton/commands.ts @@ -69,7 +69,7 @@ function executeCommand( return layer.spatialSkeletonState.commandHistory.execute(command); } -function executeCommandWithPendingMessage( +async function executeCommandWithPendingMessage( promise: Promise, message: string, ) {