You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Reference for all ObjectStack service contracts — TypeScript interfaces that define the API between the Kernel and plugins
Service Contracts Overview
Service contracts are TypeScript interfaces that define the boundaries between the ObjectStack Kernel and its plugins. Every plugin implements one or more contracts, and the Kernel consumes them through dependency injection.
**Design Principle:** Contracts contain zero business logic. They define the shape of each service — method signatures, input types, and return types — so that implementations can be swapped without changing consumers.
Why Contracts?
Benefit
Description
Decoupling
The Kernel never depends on a concrete implementation
Testability
Mock any service by implementing its contract interface
Portability
Swap SQL for NoSQL, local auth for OAuth — same contract
Type Safety
Full TypeScript inference from Zod schemas to contract interfaces
Plugin Ecosystem
Third-party plugins implement contracts to extend the platform
Contract Catalog
Data Contracts
Contract
Interface
Description
Data Engine
IDataEngine
Core data persistence — CRUD, queries, aggregations, transactions
Metadata Service
IMetadataService
Object and field definition management, schema registry
Publish/subscribe event system for triggers and realtime
Lifecycle Events
IPluginLifecycleEvents
Typed plugin and kernel lifecycle events
Logger
Logger
Structured logging with levels and context
Service Registry
IServiceRegistry
Service registration and resolution
Integration Contracts
Contract
Interface
Description
Email Service
IEmailService
Transactional and bulk email delivery
Notification Service
INotificationService
Multi-channel notifications (email, push, in-app)
Job Service
IJobService
Cron-based background job scheduling and execution
AI Contracts
Contract
Interface
Description
AI Service
IAIService
LLM inference — chat, completion, embedding
Knowledge Service
IKnowledgeService
Document indexing, retrieval, and augmented generation
Contract Structure
Every contract is a plain TypeScript interface that depends only on shared types — never on a concrete implementation:
// packages/spec/src/contracts/data-engine.tsimporttype{EngineQueryOptions,DataEngineInsertOptions,EngineUpdateOptions,EngineDeleteOptions,}from'../data/index.js';/** * IDataEngine — abstract interface for data persistence. * Plugins depend on this interface, not on concrete database implementations. */exportinterfaceIDataEngine{find(objectName: string,query?: EngineQueryOptions): Promise<any[]>;findOne(objectName: string,query?: EngineQueryOptions): Promise<any>;insert(objectName: string,data: any|any[],options?: DataEngineInsertOptions): Promise<any>;update(objectName: string,data: any,options?: EngineUpdateOptions): Promise<any>;delete(objectName: string,options?: EngineDeleteOptions): Promise<any>;// ...}
**Convention:** Contract interfaces are prefixed with `I` (e.g., `IDataEngine`). Services are registered and resolved by **string name** through the kernel service registry (e.g., `ctx.registerService('data', impl)` — see the `CoreServiceName` enum for the standard names).
Using Contracts in Plugins
Plugins declare which contracts they implement and which they consume:
importtype{Plugin}from'@objectstack/core';importtype{IDataEngine}from'@objectstack/spec/contracts';exportconstmyPlugin: Plugin={name: 'my-plugin',// Declare which other plugins must be initialized firstdependencies: ['com.objectstack.cache'],// Init phase: register the services this plugin providesinit(ctx){ctx.registerService('data',newMyDataEngine(ctx));// Consume a service another plugin registeredconstcache=ctx.getService('cache');},};
Contract Lifecycle
flowchart LR
A[Plugin Registered] --> B[Dependencies Resolved]
B --> C[init: Services Registered]
C --> D[start: Service Started]
D --> E[Ready to Serve]
E --> F[destroy: Shutdown / Teardown]
Loading
Phase
Description
Registered
Plugin is added to the kernel with its name and dependencies
Resolved
Kernel resolves the dependency graph across all plugins
Initialized
Plugin init(ctx) hook runs — services are registered
Started
Plugin start(ctx) hook runs — connections established, servers started
Ready
Contract methods are available to the Kernel and other plugins