How to Create a New Cordis Context: Instantiation and Configuration Guide
To create a new Cordis context, instantiate the Context class from @cordis/core using new Context(), which initializes a reactive proxy environment with built-in services and lifecycle management.
The cordiverse/cordis framework uses the Context class as the central runtime container for managing services, events, and plugins. When you create a new Cordis context, you establish a self-contained execution environment that supports reactive property access and hierarchical service isolation. This guide walks through the instantiation process based on the actual source implementation in the Cordis repository.
Basic Context Instantiation
To create a new Cordis context, import the Context class and call its constructor:
import { Context } from '@cordis/core'
const ctx = new Context()
This single line initializes a complete runtime environment. According to the source code in packages/core/src/context.ts (lines 36-48), the constructor performs several critical setup operations internally before returning the instance.
Internal Initialization Steps
When you invoke new Context(), the constructor executes a specific sequence defined in the source:
- Initializes isolation and intercept maps to support scoped service lookups and configuration overrides.
- Wraps the instance in a Proxy using
ReflectService.handlerto enable reactive features. - Stores a root context reference by setting
this.root = self, establishing the hierarchy root. - Creates a Fiber that manages disposal and asynchronous effects through
packages/core/src/fiber.ts. - Instantiates core services including
ReflectService,RegistryService,EventsService, andLoggerService.
After these steps complete, the context is ready to register plugins, handle effects, and manage service lifecycles.
Extending Contexts with Custom Properties
You can create child contexts that inherit from a parent while adding custom properties using the extend method:
const child = ctx.extend({ foo: 'bar' })
console.log(child.foo) // → 'bar'
This approach creates a new context that maintains the parent's service registry while overlaying additional properties. The extended context shares the same root but can carry its own isolated state for specific plugin scopes.
Isolating Sub-Contexts for Scoped Plugins
For scenarios requiring strict separation of service instances, use the isolate method to create a shadow context with a unique isolation label:
const isolated = ctx.isolate('myIsolate')
The isolated context receives its own isolation map, preventing service lookups from leaking into parent scopes. This mechanism, implemented in the core context logic, is essential for sandboxing plugins or creating tenant-specific environments within the same application.
Intercepting and Configuring Services
You can override built-in service configurations at context creation time using the intercept method:
const intercepted = ctx.intercept('logger', { level: 'debug' })
This creates a new context where the logger service operates with modified parameters without affecting the parent context's configuration. The intercept mechanism works through the internal intercept map initialized during construction.
Using Contexts in Plugins
Once created, contexts serve as the primary argument to plugin functions:
ctx.plugin(async (ctx) => {
ctx.logger.info('plugin loaded')
})
The plugin receives the context instance and can access all registered services including the event system (packages/core/src/events.ts), registry (packages/core/src/registry.ts), and reflection utilities (packages/core/src/reflect.ts).
Summary
- Import
Contextfrom@cordis/coreand callnew Context()to create a new Cordis context with full service support. - The constructor initializes five core components: isolation maps, reactive proxy wrapping, root reference assignment, Fiber creation, and core service instantiation.
- Extend contexts using
ctx.extend()to add custom properties while maintaining service inheritance. - Isolate contexts using
ctx.isolate()to create sandboxed environments with separate service lookups. - Intercept services using
ctx.intercept()to override configurations without mutating parent contexts. - Key source files include
packages/core/src/context.tsfor the main class,packages/core/src/fiber.tsfor lifecycle management, andpackages/core/src/reflect.tsfor proxy handling.
Frequently Asked Questions
What is the difference between ctx.extend() and ctx.isolate() in Cordis?
ctx.extend() creates a child context that inherits all services and properties from the parent while allowing you to add custom properties. ctx.isolate() creates a shadow context with a separate isolation label, giving it its own service lookup map that prevents inheritance from parent scopes. Use extend for adding data, and isolate for creating strict service boundaries.
How does the Cordis Context constructor manage lifecycle and disposal?
The constructor creates a Fiber instance (managed in packages/core/src/fiber.ts) that drives the context's lifecycle, handling asynchronous effects and disposal operations. This Fiber ensures that when a context is disposed, all associated resources, event listeners, and service instances are properly cleaned up through coordinated teardown logic.
Can I create a Cordis context without the default core services?
No, the Context constructor always instantiates the four core services (ReflectService, RegistryService, EventsService, LoggerService) as defined in packages/core/src/context.ts lines 36-48. These services are essential for the reactive proxy system, service registration, event handling, and logging functionality. However, you can override their configurations using ctx.intercept() to customize behavior.
What is the role of the Proxy wrapper in a new Cordis context?
The Proxy wrapper (applied via ReflectService.handler during initialization) enables the reactive property access system that allows Cordis to track service dependencies and trigger updates when service states change. This mechanism, defined in packages/core/src/reflect.ts, is what makes the context's property access interceptable and enables the framework's dependency injection capabilities.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →