Frontend Context System
Last Updated: May 19, 2025
This document provides an overview of the context system in the frontend architecture of the Typus Development Framework.
Introduction
The context system in the Typus frontend provides a structured way to manage and share state, dependencies, and functionality across components. It enables clean separation of concerns while ensuring components have access to the data and services they need.
Core Concepts
What is Context?
In the Typus framework, a context is a container that:
- Holds state (data)
- Provides methods (functionality)
- Manages dependencies (services)
- Handles lifecycle events
Contexts are designed to be hierarchical, allowing for inheritance and overriding of values at different levels of the component tree.
Context Types
The framework provides several types of contexts:
Application Context
The application context is the top-level context that is available throughout the entire application. It contains:
- Global state
- Core services
- Application configuration
- Authentication state
- Theme settings
Page Context
Each page has its own context that inherits from the application context. The page context contains:
- Page-specific state
- Navigation information
- Layout configuration
- Page-level services
Component Context
Components can create and use their own contexts, which inherit from their parent context (usually the page context). Component contexts contain:
- Component-specific state
- Local services
- Event handlers
- Computed values
DSX Contexts
When using the DSX system, contexts play a crucial role in managing data and behavior:
- DSX Page Context: Created for each DSX page, containing the page's data model and operations
- DSX Block Context: Each block in a DSX page can have its own context, either shared with the page or isolated
- DSX Component Context: Individual components within blocks can access their parent block's context or create isolated contexts
Context Hierarchy
Contexts in the Typus frontend follow a hierarchical structure:
This hierarchy allows for:
- Inheritance: Child contexts inherit properties and methods from parent contexts
- Overriding: Child contexts can override inherited values
- Isolation: Contexts can be isolated to prevent inheritance when needed
Using Contexts
Creating a Context
Contexts are typically created using composables:
// Example of creating a component context
const componentContext = useComponentContext({
initialState: {
count: 0,
items: []
},
methods: {
increment() {
this.state.count++
},
addItem(item) {
this.state.items.push(item)
}
}
})
Accessing Context
Components can access their context or parent contexts:
// Access the current component's context
const context = useCurrentContext()
// Access the page context
const pageContext = usePageContext()
// Access the application context
const appContext = useAppContext()
Context in DSX
In DSX pages, contexts are automatically created based on configuration:
const pageConfig = {
// ...
contextConfig: {
model: UserModel, // DSL model binding
mode: FormMode.EDIT,
recordId: userId
},
blocks: [
{
// This block uses the page context
components: [/* ... */]
},
{
// This block has an isolated context
contextConfig: {
scope: ContextScope.ISOLATED,
model: UserPreferencesModel
},
components: [/* ... */]
}
]
}
Context Features
Reactive State
All context state is reactive, meaning changes to the state automatically trigger UI updates in components that depend on that state.
Method Binding
Methods defined in a context are automatically bound to that context, allowing them to access and modify the context's state.
Dependency Injection
Contexts can inject dependencies from parent contexts or from the dependency injection container:
const context = useComponentContext({
inject: ['userService', 'notificationService'],
methods: {
async saveUser() {
await this.userService.save(this.state.user)
this.notificationService.success('User saved')
}
}
})
Lifecycle Hooks
Contexts provide lifecycle hooks that allow for setup and cleanup operations:
onContextCreated
: Called when the context is first createdonContextMounted
: Called when the component using the context is mountedonContextBeforeUnmount
: Called before the component using the context is unmountedonContextUnmounted
: Called when the component using the context is unmounted
Context and DSL Integration
The context system integrates seamlessly with the DSL (Domain-Specific Language) system:
- DSL models can be bound to contexts
- Context methods can perform DSL operations
- DSL events can trigger context updates
- Context state can be synchronized with DSL data
This integration is particularly powerful in DSX pages, where the context automatically handles data loading, saving, and synchronization based on the configured DSL model.
Best Practices
Context Granularity
- Application Context: Use for truly global state and services
- Page Context: Use for state shared across components on a page
- Component Context: Use for state specific to a component and its children
- Isolated Context: Use when a component needs to be self-contained
State Management
- Keep context state focused and minimal
- Use computed values for derived state
- Consider using Pinia stores for complex global state
Performance Considerations
- Avoid deep nesting of contexts when possible
- Be mindful of reactive dependencies to prevent unnecessary re-renders
- Use isolated contexts for performance-critical components
Conclusion
The context system in the Typus frontend provides a powerful and flexible way to manage state and functionality across components. By leveraging contexts, developers can create clean, maintainable code with clear separation of concerns while ensuring components have access to the data and services they need.
The integration with DSX and DSL systems makes the context system particularly powerful for building dynamic, data-driven interfaces with minimal code.