Workspace Types
Relevant source files
The following files were used as context for generating this wiki page:
This page documents the TypeScript type definitions that represent workspace data at different stages of processing. These types form the data model layer between the Rust backend's file system operations and the Vue frontend's reactive state.
For information about the parsed board and card document types, see Kanban Parser Schema. For information about how workspaces are loaded and managed in the frontend, see useWorkspace.
Overview
The workspace type system is organized into three layers:
- Raw Data Layer:
WorkspaceFileSnapshotandWorkspaceSnapshot- represent unparsed file contents from the backend - Selection Types:
WorkspaceCardSelectionandVisibleBoardCardSelection- represent user selections in the UI - Indexed Data Layer:
LoadedWorkspace- combines raw data, parsed results, and indexed lookups for efficient access - Mutation Types:
WorkspaceMutationPayload- represent atomic state updates
All types are defined in src/types/workspace.ts.
Sources: src/types/workspace.ts:1-41
Type Hierarchy
Workspace Type Relationships
Sources: src/types/workspace.ts:1-41, src/utils/workspaceSnapshot.ts:1-36
Raw Data Layer
WorkspaceFileSnapshot
Represents a single file's snapshot with its path and content.
| Field | Type | Description |
|---|---|---|
path | string | Relative path from workspace root (e.g., TODO/todo.md, TODO/cards/task-1.md) |
content | string | Raw markdown file content |
Definition: src/types/workspace.ts:3-6
This type is used as the basic unit of file data. The Rust backend reads files from disk and creates these snapshots, which are then sent to the frontend.
Sources: src/types/workspace.ts:3-6
WorkspaceSnapshot
Represents the complete raw workspace state returned from the backend.
| Field | Type | Description |
|---|---|---|
rootPath | string | Absolute file system path to workspace root directory |
rootBoardPath | string | Relative path to the root board file (typically TODO/todo.md) |
boards | WorkspaceFileSnapshot[] | Array of all board file snapshots in the workspace |
cards | WorkspaceFileSnapshot[] | Array of all card file snapshots in the workspace |
Definition: src/types/workspace.ts:8-13
This is the primary data structure returned by the load_workspace Rust command (see Backend Command Handlers). It contains no parsed or indexed data - just raw file paths and contents.
Example structure:
{
rootPath: "/Users/name/projects/my-project",
rootBoardPath: "TODO/todo.md",
boards: [
{ path: "TODO/todo.md", content: "# Main Board\n\n## Todo\n..." },
{ path: "project-a/TODO/todo.md", content: "# Project A\n..." }
],
cards: [
{ path: "TODO/cards/task-1.md", content: "---\ntitle: Task 1\n---\n..." },
{ path: "TODO/cards/task-2.md", content: "---\ntitle: Task 2\n---\n..." }
]
}Sources: src/types/workspace.ts:8-13, src/utils/workspaceSnapshot.ts:5-6, src/utils/boardMarkdown.test.ts:198-203
Selection Types
WorkspaceCardSelection
Represents a card that is currently selected by the user.
| Field | Type | Description |
|---|---|---|
slug | string | Full card slug (e.g., TODO/cards/task-1) |
sourceBoardSlug | string | Slug of the board containing this card (e.g., TODO) |
Definition: src/types/workspace.ts:15-18
This type identifies a selected card by its slug and the board it belongs to. The sourceBoardSlug is necessary because the same card might be visible on multiple boards through sub-board relationships.
Sources: src/types/workspace.ts:15-18
VisibleBoardCardSelection
Extends WorkspaceCardSelection with positional information for cards visible on the current board.
| Field | Type | Description |
|---|---|---|
slug | string | Inherited from WorkspaceCardSelection |
sourceBoardSlug | string | Inherited from WorkspaceCardSelection |
columnIndex | number | Zero-based index of the column containing this card |
rowIndex | number | Zero-based index of the card within its column |
Definition: src/types/workspace.ts:20-23
This extended type is used for keyboard navigation and multi-selection features (see useBoardSelection). The columnIndex and rowIndex fields enable arrow key navigation and range selection.
Sources: src/types/workspace.ts:20-23
Mutation Layer
WorkspaceMutationPayload
Represents an atomic workspace state update, typically resulting from a user action.
| Field | Type | Description |
|---|---|---|
currentBoardSlug | string | null | undefined | Optional: new current board slug to navigate to |
selectedCard | WorkspaceCardSelection | null | undefined | Optional: new card selection state |
snapshot | WorkspaceSnapshot | Required: updated workspace snapshot from backend |
Definition: src/types/workspace.ts:25-29
This type is used when backend operations complete and return updated workspace state. It bundles the new snapshot with optional navigation/selection updates. The undefined vs null distinction matters:
undefined: don't change this aspect of statenull: explicitly clear this aspect of state- Non-null value: set to this value
Usage pattern:
// After saving a card, update workspace and maintain selection
const payload: WorkspaceMutationPayload = {
selectedCard: undefined, // keep current selection
snapshot: updatedSnapshot // new workspace state
}
// After deleting a card, update workspace and clear selection
const payload: WorkspaceMutationPayload = {
selectedCard: null, // clear selection
snapshot: updatedSnapshot
}
// After creating a board, navigate to it
const payload: WorkspaceMutationPayload = {
currentBoardSlug: newBoardSlug, // navigate to new board
snapshot: updatedSnapshot
}Sources: src/types/workspace.ts:25-29
Indexed Data Layer
LoadedWorkspace
Represents a fully processed workspace with parsed documents and indexed lookups.
| Field | Type | Description |
|---|---|---|
rootPath | string | Workspace root absolute path |
rootBoardSlug | string | Slug of the root board (e.g., TODO) |
snapshot | WorkspaceSnapshot | Original raw snapshot from backend |
parseResult | KanbanParseResult | Parsed board and card documents with diagnostics |
boardsBySlug | Record<string, KanbanBoardDocument> | Map for O(1) board lookup by slug |
boardFilesBySlug | Record<string, WorkspaceFileSnapshot> | Map for O(1) board file lookup by slug |
cardsBySlug | Record<string, KanbanCardDocument> | Map for O(1) card lookup by slug |
boardOrder | string[] | Ordered array of board slugs for iteration |
Definition: src/types/workspace.ts:31-40
This is the primary data structure used by the frontend. It combines:
- Raw snapshot data for reference and persistence
- Parsed, typed documents from
KanbanParseResult(see Kanban Parser Schema) - Indexed maps for efficient lookups by slug
- Ordered arrays for deterministic iteration
The LoadedWorkspace is constructed by the buildLoadedWorkspace() function, which takes a WorkspaceSnapshot and transforms it into this indexed structure.
Sources: src/types/workspace.ts:31-40, src/utils/workspaceSnapshot.ts:5-27
Transformation Pipeline
Data Flow from Backend to Frontend State
Sources: src/utils/workspaceSnapshot.ts:5-27, src/utils/parseWorkspace.ts
Helper Functions
buildLoadedWorkspace
Transforms a WorkspaceSnapshot into a LoadedWorkspace by parsing and indexing the data.
Signature: buildLoadedWorkspace(snapshot: WorkspaceSnapshot): LoadedWorkspace
Location: src/utils/workspaceSnapshot.ts:5-27
Implementation overview:
- Parse snapshot using
parseWorkspace()to getKanbanParseResult - Build
boardsBySlugmap from parsed boards - Build
boardFilesBySlugmap usingboardIdFromBoardPath()helper - Build
cardsBySlugmap from parsed cards - Extract
boardOrderarray from parsed boards - Compute
rootBoardSlugfromsnapshot.rootBoardPath
Sources: src/utils/workspaceSnapshot.ts:5-27, src/utils/kanbanPath.ts:88-90
createWorkspaceSnapshotSignature
Creates a stable string signature for comparing workspace snapshots.
Signature: createWorkspaceSnapshotSignature(snapshot: WorkspaceSnapshot): string
Location: src/utils/workspaceSnapshot.ts:29-35
This function serializes the snapshot to JSON for comparison purposes. It's used to detect when a workspace has changed and needs re-parsing. The signature includes rootBoardPath, boards, and cards arrays.
Sources: src/utils/workspaceSnapshot.ts:29-35
Usage Patterns
Loading a Workspace
// 1. Backend returns WorkspaceSnapshot
const snapshot: WorkspaceSnapshot = await invoke('load_workspace', { path })
// 2. Transform into LoadedWorkspace
const loaded = buildLoadedWorkspace(snapshot)
// 3. Access indexed data
const rootBoard = loaded.boardsBySlug[loaded.rootBoardSlug]
const card = loaded.cardsBySlug['TODO/cards/task-1']Sources: src/utils/workspaceSnapshot.ts:5-27
Applying Mutations
// After a backend operation that modifies files
const payload: WorkspaceMutationPayload = {
currentBoardSlug: undefined, // maintain navigation
selectedCard: {
slug: 'TODO/cards/new-card',
sourceBoardSlug: 'TODO'
},
snapshot: updatedSnapshot // from backend
}
// Transform and apply to state
const newLoaded = buildLoadedWorkspace(payload.snapshot)
// Update reactive state with newLoaded and payload.selectedCardSources: src/types/workspace.ts:25-29
Iterating Boards in Order
// Use boardOrder for deterministic iteration
for (const boardSlug of loaded.boardOrder) {
const board = loaded.boardsBySlug[boardSlug]
const boardFile = loaded.boardFilesBySlug[boardSlug]
// Process board...
}Sources: src/types/workspace.ts:39, src/utils/workspaceSnapshot.ts:14
Type Safety Benefits
The workspace type system provides several type safety guarantees:
- Separation of Concerns: Raw data (
WorkspaceSnapshot) is clearly separated from parsed data (LoadedWorkspace) - Explicit Nullability: The mutation payload uses
T | null | undefinedto distinguish between "keep", "clear", and "set" operations - Indexed Access: The
Record<string, T>maps inLoadedWorkspaceensure type-safe lookups - Immutability: All types are interfaces with readonly semantics (no mutating methods)
Sources: src/types/workspace.ts:1-41
Related Types
For types related to the parsed board and card documents stored in LoadedWorkspace, see:
- KanbanParseResult - The parsed output from
parseWorkspace() - KanbanBoardDocument - Typed board structure
- KanbanCardDocument - Typed card structure
For information about how these types are used in the application state, see:
- useWorkspace composable - Manages
LoadedWorkspacein reactive state - Workspace Operations - Backend functions that produce
WorkspaceSnapshot
Sources: src/types/workspace.ts:1
