Frontend: State Management
Relevant source files
The following files were used as context for generating this wiki page:
The frontend state management in Nucleus is built upon Svelte's writable stores, organized into a modular and domain-specific architecture. Each major feature or data entity (like Account, App, Collections, Capture) has its own dedicated store. This approach encapsulates logic and state, promoting separation of concerns.
A base ResourceStore class provides a common foundation for managing data resources, while the ActiveResourceStore pattern is used for handling the state of transient, interactive user sessions, such as content capturing. A global map, globalStoresMap, acts as a service locator, providing a centralized point of access to the various data stores throughout the application.
Core Architecture
The state management relies on a class-based extension of Svelte stores. The core of this architecture is a set of base classes that provide common functionality for resource management.
Sources: client/products/memotron/capture/capture.store.ts:110-114, client/products/memotron/capture/capture.store.ts:120-129
ResourceStore and ActiveResourceStore
Many stores in the application, especially those dealing with persistent data, are built upon ResourceStore and ActiveResourceStore.
ResourceStore: A generic class for managing a collection of resources of a specific type (e.g.,CollectionStoremanages collections). It typically provides CRUD-like functionalities.ActiveResourceStore: This class is designed to manage the state of a single, "active" resource or session. A prime example is theActiveCaptureStore, which manages the state of the content capture UI. It handles transient data that will either be saved as a new resource or discarded.
The diagram below illustrates the inheritance and composition relationship for the capture feature.
Global Store Registry
A central registry, globalStoresMap, holds instances of major resource stores. This allows different parts of the application to retrieve a store instance by its Resource enum type, implementing a service locator pattern.
// client/stores/globalStoresMap.ts:5-14
export const globalStoresMap = new Map<
Resource,
| INodeStore
| ICollectionStore
| ITypeStore
| ICombinationStore
| IGoalStore
| ITaskStore
| IEventStore
>();
This map is populated with instances of stores like nodeStore, collectionStore, and typeStore.
Sources: client/stores/globalStoresMap.ts:5-14
Global Stores
These stores manage application-wide state and are fundamental to the user experience.
app.store.ts
The AppStore is the central hub for managing the application's UI state, particularly which resources are currently being displayed.
| Method | Description |
|---|---|
openResource(id, accessMode) | Opens a resource in the UI, supporting different access modes like POP (popup) or MAIN. |
closeResource(params) | Closes a specific resource view. |
addToRecents(item) | Adds a recently accessed resource to the user's history. |
setOnlineStatus(isOnline) | Updates the application's network connectivity status. |
Sources: client/stores/app.store.ts
account.store.ts
The AccountStore handles all user-related data and actions, including authentication and file management.
The state managed by this store includes:
userInfo: Information about the logged-in user.isAuthenticated: A boolean flag indicating the user's authentication status.dataMode: The current data persistence mode (CLOUDorLOCAL).
A critical function of this store is uploadFileV2, which is used by other stores (like CaptureStore) to upload files to the backend.
Sources: client/stores/account.store.ts, client/products/memotron/capture/capture.store.ts:742-752
collection.store.ts
The CollectionStore is responsible for managing "Collections" and "Types," which are fundamental organizational structures within the application. It extends the base ResourceStore and provides methods to create, read, update, and delete collections. The CaptureStore interacts with it to associate new content with existing collections.
Sources: client/components/collection/collection.store.ts, client/products/memotron/capture/capture.store.ts:400-402
Feature-Specific Stores: capture.store.ts
The capture.store.ts file is an excellent example of a complex, feature-specific state management implementation. It handles the entire lifecycle of capturing new content, from text and files to audio recordings.
ActiveCaptureStore
This class manages the state of the capture UI. It holds the content being created (body), associated links (links), properties (properties), and the chosen capture method (method).
The CaptureMethod enum defines the different types of content that can be captured:
| Capture Method | Description |
|---|---|
MARKDOWN | Capturing rich text content. |
AUDIO | Recording audio. |
CAMERA | Capturing from a device camera. |
WEBPAGE | Saving a web page from a URL. |
FILE | Uploading a generic file. |
Sources: client/products/memotron/capture/capture.store.ts:23-29
Data Capture and Save Flow
The process of saving new content involves coordination between multiple stores. The sequence diagram below shows the flow for saving a markdown capture.
This diagram illustrates how ActiveCaptureStore orchestrates the creation of nodes via nodeStore, establishes relationships via linker, and finally uses appStore to navigate the user to the newly created content.
Sources: client/products/memotron/capture/capture.store.ts:1010-1088, client/products/memotron/capture/capture.store.ts:948-971, client/products/memotron/capture/capture.store.ts:989-1004
The saveFile method shows a similar pattern but includes an initial step to upload the file using the account store.
Summary
The frontend state management in Nucleus is robust and scalable. It leverages Svelte's reactivity through a well-defined, class-based store system. The clear separation between global stores (app, account) and feature-specific stores (capture), combined with the ResourceStore pattern and a central globalStoresMap, creates a maintainable and organized architecture for managing application state.