Workspace State Management
Relevant source files
The following files were used as context for generating this wiki page:
Workspace State Management coordinates the reactive data flow between the persistent project library, the active learning domain, and asynchronous generation workflows. It ensures that the user interface stays synchronized with the underlying course data, playback progress, and background AI operations.
Architecture Overview
The system architecture separates transient session state from the authoritative domain data. The useWorkspaceControllerState hook manages UI-specific states like navigation, diagnostic adapters, and active workflow statuses. Authoritative project data resides in the WorkspaceDomainState, which is modified through a centralized reducer pattern.
The following diagram illustrates the relationship between the controller state, the domain state, and the external library services:
Workspace Domain State
The WorkspaceDomainState represents the complete state of a learning project. It includes the course content, user preferences, and research data. The workspaceDomainReducer handles all modifications to this state, ensuring atomic updates for complex structures like the LearningPlan.
Domain Components
| Field | Description |
|---|---|
source | The primary input material (PDF, ZIP, or Text). |
learningPlan | The hierarchical structure of modules and lessons. |
documentIndex | The processed text index for source material. |
userProfile | Learner-specific preferences and assessment data. |
activeSectionId | The ID of the lesson or exercise currently in view. |
researchDossiers | External context gathered for lesson generation. |
Sources: apps/web/services/workspace/domain.ts:9-25, apps/web/hooks/workspace/controller/types.ts:46-77
State Transitions
Data enters the domain through hydration from a ProjectSnapshot. Once hydrated, the domain state is updated via actions that modify specific fields or tree nodes.
Workflow Management
Workflows track long-running asynchronous operations, such as generating a course plan or creating a lesson. Each workflow is identified by a WorkspaceWorkflowId and maintains its status, progress, and error state.
Workflow Lifecycle
- Begin: The controller assigns a new
requestIdand sets the status topending. - Progress: Background tasks update the
progresssnapshot and optionalreasoningtext. - Completion: The workflow transitions to either
succeededorfailed.
Blocking Workflows
Certain workflows are designated as "blocking" if they prevent further user interaction with the project.
openProjectattachSourcegeneratePlanassessmentcompleteSection
The selectIsBlocking helper checks if any of these critical operations are in a pending status.
Sources: apps/web/services/workspace/workflow.ts:55-61, apps/web/services/workspace/workflow.ts:63-79
Generation State Coordination
The workspace tracks active AI generation tokens to prevent race conditions and ensure that background tasks reattach to the correct UI components if the user navigates away and returns.
- Generation Tokens: Every generation attempt receives a unique
token. The state only accepts updates if thetokenremains current for thatprojectId. - Reattachment Handlers: The controller stores
onReattachcallbacks. If a user returns to a generating lesson, the UI callsreattachLessonGenerationto restore the active state. - Generating Section Tracking:
generatingSectionIdidentifies which specific part of the learning plan is currently being modified by the AI.
Sources: apps/web/hooks/workspace/controller/state.ts:167-195, apps/web/hooks/workspace/controller/state.ts:238-255
Persistence and Autosave
The useProjectLibrary hook (referenced via WorkspaceProjectLibraryAdapter) coordinates with the workspace domain to ensure data safety.
- Snapshots: The controller generates a
ProjectSnapshotfrom the currentWorkspaceDomainState. - Patching: For small updates like changing the active section, the controller uses
patchCurrentProjectto send granular updates. - Autosave: The system monitors a "persistence signature" (a hash of the domain state). If the current signature differs from the
lastPersistedSignature, an autosave is triggered after a brief debounce period.
Sources: apps/web/hooks/workspace/controller/types.ts:79-138, apps/web/hooks/workspace/controller/controllerContext.ts:121-137