Stateful context services and the ContextService abstraction for managing application state in GraphDB Workbench.
This guide introduces the ContextService API, a versatile abstraction for managing application context in the GraphDB
Workbench application. Each view in the application is expected to implement a concrete version of the ContextService
API, tailored to its specific requirements.
The ContextService API facilitates state management by:
The API is implemented as an abstract class, requiring developers to define specific fields and methods for their application’s needs.
ContextServiceThe ContextService class is generic and requires a type parameter TFields that defines the fields the service can
handle. Each field corresponds to a property of the service and is managed via the context map.
Key methods include:
updateContextProperty: Updates the value of a property.
getContextPropertyValue: Retrieves the current value of a property.
subscribe: Registers a callback to be notified of property value changes.
SnakeToPascalCase
Converts SNAKE_CASE field names to PascalCase for method naming.
DeriveContextServiceContract
Generates update methods for each field. For example, a field SELECTED_REPOSITORY generates an
updateSelectedRepository method.
RepositoryContextServiceThe RepositoryContextService class manages repository-related application context for views in the GraphDB Workbench.
It implements the abstract ContextService and provides methods for updating and subscribing to repository-related data.
readonly SELECTED_REPOSITORY = 'selectedRepository';
readonly REPOSITORY_LIST = 'repositoryList';
These fields define the context properties managed by the service.
Updating Context
updateSelectedRepository(repository: Repository | undefined): void
Updates the selected repository.
updateRepositoryList(repositories: RepositoryList): void
Updates the list of repositories.
Subscribing to Changes
onSelectedRepositoryChanged(callbackFunction: ValueChangeCallback<Repository | undefined>): () => void
Subscribes to changes in the selected repository.
onRepositoriesChanged(callbackFunction: ValueChangeCallback<RepositoryList | undefined>): () => void
Subscribes to changes in the repository list.
ContextService1. Define Context Fields and Parameters
Define the fields and their corresponding parameter types:
type RepositoryContextFields = {
readonly SELECTED_REPOSITORY: string;
readonly REPOSITORY_LIST: string;
};
type RepositoryContextFieldParams = {
readonly SELECTED_REPOSITORY: Repository;
readonly REPOSITORY_LIST: RepositoryList;
};
2. Extend ContextService
Implement a concrete class that extends ContextService:
export class RepositoryContextService extends ContextService<RepositoryContextFields> implements DeriveContextServiceContract<RepositoryContextFields, RepositoryContextFieldParams> {
readonly SELECTED_REPOSITORY = 'selectedRepository';
readonly REPOSITORY_LIST = 'repositoryList';
updateSelectedRepository(repository: Repository | undefined): void {
this.updateContextProperty(this.SELECTED_REPOSITORY, repository);
}
onSelectedRepositoryChanged(callbackFunction: ValueChangeCallback<Repository | undefined>): () => void {
return this.subscribe(this.SELECTED_REPOSITORY, callbackFunction);
}
updateRepositoryList(repositories: RepositoryList): void {
this.updateContextProperty(this.REPOSITORY_LIST, repositories);
}
onRepositoriesChanged(callbackFunction: ValueChangeCallback<RepositoryList | undefined>): () => void {
return this.subscribe(this.REPOSITORY_LIST, callbackFunction);
}
}
3. Using the Service
Import the Service using the ServiceProvider API:
Warning: Everything in the api package must be imported using the alias
@ontotext/workbench-apiand not by relative or absolute paths. The reason for this is that the api module is a separate package managed as a microservice which is loaded using import maps where the alias is defined.
import { ServiceProvider, RepositoryContextService } from '@ontotext/workbench-api';
// Get the service instance
const repositoryContextService = ServiceProvider.get(RepositoryContextService);
Update Context Values:
const repository: Repository = { id: 1, name: 'Repo1' };
repositoryContextService.updateSelectedRepository(repository);
const repositoryList: RepositoryList = [{ id: 1, name: 'Repo1' }, { id: 2, name: 'Repo2' }];
repositoryContextService.updateRepositoryList(repositoryList);
4. Subscribe to Changes
const unsubscribeSelectedRepository = repositoryContextService.onSelectedRepositoryChanged((newRepository) => {
console.log('Selected repository changed:', newRepository);
});
const unsubscribeRepositoryList = repositoryContextService.onRepositoriesChanged((newList) => {
console.log('Repository list changed:', newList);
});
// To unsubscribe:
unsubscribeSelectedRepository();
unsubscribeRepositoryList();
The ContextService API provides a simple yet powerful mechanism for managing context in GraphDB Workbench views. By
extending ContextService, developers can create view-specific services that streamline state management and improve
code maintainability.
See also: Developers Guide