This document explains the integration of @objectstack/runtime and @objectstack/objectql into the ObjectQL platform.
As of version 4.0.0, ObjectQL core uses the ObjectStack runtime packages with plugin architecture:
- @objectstack/spec@0.2.0: Protocol specification with standard
DriverInterface - @objectstack/objectql@0.2.0: Core ObjectQL engine with driver management
- @objectstack/runtime@0.2.0: Runtime kernel with application lifecycle orchestration and plugin system
@objectql/core (this package)
├── Wraps ObjectStackKernel from @objectstack/runtime
├── Implements ObjectQLPlugin for enhanced features
├── Uses @objectstack/objectql for driver management
├── Natively uses @objectstack/spec.DriverInterface (no wrapper)
└── Re-exports types from @objectstack/runtime
Breaking Change (v4.0.0): The core package now wraps ObjectStackKernel and uses a plugin architecture:
import { ObjectQL, ObjectQLPlugin } from '@objectql/core';
import type { DriverInterface } from '@objectstack/spec';
// ObjectQL now wraps ObjectStackKernel internally
const app = new ObjectQL({
datasources: {
default: myDriver // Must be DriverInterface
}
});
// Access the kernel if needed
const kernel = app.getKernel();
await app.init(); // This calls kernel.start() internallyThe new ObjectQLPlugin class implements the RuntimePlugin interface from @objectstack/runtime:
import { ObjectQLPlugin, ObjectQLPluginConfig } from '@objectql/core';
// Configure the plugin
const plugin = new ObjectQLPlugin({
enableRepository: true,
enableValidator: true,
enableFormulas: true,
enableAI: true
});
// The plugin is automatically registered when you create an ObjectQL instance
const app = new ObjectQL({ datasources: {} });The core package exports types from the ObjectStack packages:
// Driver development types
export type {
DriverInterface,
DriverOptions,
QueryAST
} from '@objectstack/spec';
// Runtime integration types
export type {
ObjectStackKernel,
ObjectStackRuntimeProtocol
} from '@objectstack/runtime';
export type {
ObjectQL as ObjectQLEngine,
SchemaRegistry
} from '@objectstack/objectql';The current ObjectQL class in this package is a production-ready, feature-rich implementation that includes:
- Full metadata registry
- Hooks system
- Actions system
- Validation engine
- Repository pattern
- Formula engine
- AI integration
- Wraps ObjectStackKernel for plugin architecture
- Native driver management via @objectstack/objectql
The ObjectQLEngine from @objectstack/objectql is a simpler, lightweight implementation suitable for:
- Basic CRUD operations
- Simple driver management
- Minimal runtime overhead
ObjectQL now wraps the ObjectStackKernel to provide plugin architecture and lifecycle management:
// In @objectql/core
import { ObjectStackKernel } from '@objectstack/runtime';
import { ObjectQLPlugin } from './plugin';
export class ObjectQL implements IObjectQL {
private kernel: ObjectStackKernel;
private kernelPlugins: any[] = [];
constructor(config: ObjectQLConfig) {
// Add the ObjectQL plugin to provide enhanced features
this.kernelPlugins.push(new ObjectQLPlugin());
// Create the kernel instance
this.kernel = new ObjectStackKernel(this.kernelPlugins);
}
async init() {
console.log('[ObjectQL] Initializing with ObjectStackKernel...');
// Start the kernel first - this will install and start all plugins
await this.kernel.start();
// Continue with legacy initialization...
}
/**
* Get the underlying ObjectStackKernel instance
* for advanced usage scenarios
*/
getKernel(): ObjectStackKernel {
return this.kernel;
}
}ObjectQL now directly uses drivers conforming to @objectstack/spec.DriverInterface:
// In @objectql/core
import { DriverInterface } from '@objectstack/spec';
private datasources: Record<string, DriverInterface> = {};
private stackEngine: ObjectStackEngine;
constructor(config: ObjectQLConfig) {
this.stackEngine = new ObjectStackEngine({});
// Register drivers directly (no wrapping)
for (const [name, driver] of Object.entries(config.datasources)) {
this.stackEngine.registerDriver(driver, name === 'default');
}
}The ObjectStack engine handles all driver lifecycle management:
async close() {
// ObjectStack engine manages all driver disconnect logic
await this.stackEngine.destroy();
}To build custom drivers for ObjectStack, implement DriverInterface from @objectstack/spec:
import { DriverInterface, QueryAST } from '@objectstack/spec';
export class MyCustomDriver implements DriverInterface {
name = 'MyDriver';
version = '1.0.0';
async connect() {
// Initialize connection
}
async disconnect() {
// Close connection
}
async find(object: string, query: QueryAST, options?: any) {
// Query implementation
return [];
}
async create(object: string, data: any, options?: any) {
// Create implementation
return data;
}
async update(object: string, id: string, data: any, options?: any) {
// Update implementation
return data;
}
async delete(object: string, id: string, options?: any) {
// Delete implementation
}
}Register with ObjectQL:
import { ObjectQL } from '@objectql/core';
import { MyCustomDriver } from './my-driver';
const app = new ObjectQL({
datasources: {
default: new MyCustomDriver()
}
});
// Or register dynamically
app.registerDriver('mydb', new MyCustomDriver(), false);What Changed:
ObjectQLnow wrapsObjectStackKernelfrom@objectstack/runtime- New
ObjectQLPluginclass implementsRuntimePlugininterface - Initialization process now calls
kernel.start()which installs and starts all plugins - Dependencies updated to
@objectstack/*@0.2.0 - New
getKernel()method provides access to the underlying kernel - Removed legacy plugin support - all plugins must now implement the
RuntimePlugininterface
Migration Guide:
The ObjectQL API remains the same:
import { ObjectQL } from '@objectql/core';
import { MyDriver } from './my-driver';
const app = new ObjectQL({
datasources: {
default: new MyDriver()
}
});
await app.init(); // Calls kernel.start() internallyAccess the kernel for advanced use cases:
const kernel = app.getKernel(); // Must call after init()Plugin Migration:
Old plugins with onEnable hook are no longer supported. Migrate to RuntimePlugin:
// Old (no longer supported)
const plugin = {
id: 'my-plugin',
onEnable: async (context) => {
// initialization logic
}
};
// New (required)
import type { RuntimePlugin, RuntimeContext } from '@objectstack/runtime';
class MyPlugin implements RuntimePlugin {
name = 'my-plugin';
async install(ctx: RuntimeContext): Promise<void> {
// installation logic
}
async onStart(ctx: RuntimeContext): Promise<void> {
// startup logic
}
}
const plugin = new MyPlugin();What Changed:
ObjectQLConfig.datasourcesnow requiresRecord<string, DriverInterface>(from@objectstack/spec)- Removed compatibility wrapper for old
Drivertype app.datasource()now returnsDriverInterface- Driver lifecycle is fully managed by ObjectStack engine
Migration Guide:
Old code (deprecated):
import { Driver } from '@objectql/types';
class MyDriver implements Driver {
// Old Driver interface
}New code (required):
import { DriverInterface, QueryAST } from '@objectstack/spec';
class MyDriver implements DriverInterface {
name = 'MyDriver';
version = '1.0.0';
async connect() { }
async disconnect() { }
async find(object: string, query: QueryAST, options?: any) { }
async create(object: string, data: any, options?: any) { }
async update(object: string, id: string, data: any, options?: any) { }
async delete(object: string, id: string, options?: any) { }
}import { ObjectQL } from '@objectql/core';
import { MemoryDriver } from '@objectql/driver-memory';
const app = new ObjectQL({
datasources: { default: new MemoryDriver() }
});
await app.init();
const ctx = app.createContext({ userId: 'user123' });
const repo = ctx.object('todo');
const items = await repo.find({});import type { DriverInterface, QueryAST } from '@objectql/core';
// Use types for compile-time checking (type-only import)
function validateQuery(query: QueryAST): boolean {
return query.object !== undefined;
}- @objectstack/spec@0.1.2: Standard
DriverInterfaceprotocol - @objectstack/objectql@0.1.1: Provides driver registration and lifecycle management
- Breaking Change: Old
Drivertype from@objectql/typesis no longer supported - Tests: All tests updated to use
DriverInterface
The native integration with @objectstack/objectql enables:
- Standardized driver interface across the ObjectStack ecosystem
- Plugin system for extending driver capabilities
- Unified driver management across multiple packages
- Driver marketplace and discovery