From f43fc7742f432e3b3eab86d1560b3044cbc3b91e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 03:42:55 +0000 Subject: [PATCH 1/7] Initial plan From 37cf6c527ac270d17e86402fcc52d7ea0524dc10 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 03:46:52 +0000 Subject: [PATCH 2/7] Remove ObjectStackKernel implementation and update runtime code Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- .../plugin-hono-server/src/hono-plugin.ts | 3 +- packages/plugin-msw/src/msw-plugin.ts | 12 +- packages/runtime/src/index.ts | 7 - packages/runtime/src/kernel.ts | 229 ------------------ packages/runtime/src/objectql-plugin.ts | 19 +- packages/runtime/src/protocol.ts | 60 +---- packages/runtime/src/types.ts | 21 +- test-objectql-plugin.ts | 98 ++++---- 8 files changed, 67 insertions(+), 382 deletions(-) delete mode 100644 packages/runtime/src/kernel.ts diff --git a/packages/plugin-hono-server/src/hono-plugin.ts b/packages/plugin-hono-server/src/hono-plugin.ts index a45214918..261ce5220 100644 --- a/packages/plugin-hono-server/src/hono-plugin.ts +++ b/packages/plugin-hono-server/src/hono-plugin.ts @@ -63,8 +63,7 @@ export class HonoServerPlugin implements Plugin, RuntimePlugin { * Start phase - Bind routes and start listening */ async start(ctx: PluginContext) { - // Try to get ObjectStackKernel for backward compatibility - // In new architecture, we'd get ObjectQL directly from services + // Get ObjectQL directly from services let protocol: ObjectStackRuntimeProtocol | null = null; try { diff --git a/packages/plugin-msw/src/msw-plugin.ts b/packages/plugin-msw/src/msw-plugin.ts index a15e147b0..c4f6182b4 100644 --- a/packages/plugin-msw/src/msw-plugin.ts +++ b/packages/plugin-msw/src/msw-plugin.ts @@ -162,22 +162,12 @@ export class ObjectStackServer { * ```typescript * import { MSWPlugin } from '@objectstack/plugin-msw'; * - * // With new ObjectKernel + * // With ObjectKernel * const kernel = new ObjectKernel(); * kernel.use(new MSWPlugin({ * enableBrowser: true, * baseUrl: '/api/v1' * })); - * - * // With legacy ObjectStackKernel - * const runtime = new ObjectStackRuntime({ - * plugins: [ - * new MSWPlugin({ - * enableBrowser: true, - * baseUrl: '/api/v1' - * }) - * ] - * }); * ``` */ export class MSWPlugin implements Plugin, RuntimePlugin { diff --git a/packages/runtime/src/index.ts b/packages/runtime/src/index.ts index 8558de084..20b376614 100644 --- a/packages/runtime/src/index.ts +++ b/packages/runtime/src/index.ts @@ -4,13 +4,6 @@ export { ObjectQL, SchemaRegistry } from '@objectstack/objectql'; // Export Kernels export { ObjectKernel } from './mini-kernel.js'; -/** - * @deprecated Use ObjectKernel instead for better modularity and plugin architecture. - * ObjectStackKernel is kept for backward compatibility only. - * @see {ObjectKernel} - The recommended MiniKernel implementation - */ -export { ObjectStackKernel } from './kernel.js'; - // Export Plugins export { ObjectQLPlugin } from './objectql-plugin.js'; export { DriverPlugin } from './driver-plugin.js'; diff --git a/packages/runtime/src/kernel.ts b/packages/runtime/src/kernel.ts deleted file mode 100644 index dc530b25b..000000000 --- a/packages/runtime/src/kernel.ts +++ /dev/null @@ -1,229 +0,0 @@ -import { ServiceObject } from '@objectstack/spec/data'; -import { SchemaRegistry, ObjectQL } from '@objectstack/objectql'; - -/** - * ObjectStack Kernel (Legacy) - * - * @deprecated Use ObjectKernel (MiniKernel) instead for better modularity and plugin architecture. - * This class is kept for backward compatibility but new projects should use ObjectKernel. - * - * @see ObjectKernel - The new MiniKernel implementation - * @see MINI_KERNEL_GUIDE.md - Complete guide to the new architecture - * - * The legacy kernel orchestrates the application lifecycle, - * plugins, and the core ObjectQL engine, but with less modularity - * than the new ObjectKernel implementation. - * - * Migration example: - * ```typescript - * // Old (deprecated): - * const kernel = new ObjectStackKernel([ - * new ObjectQLPlugin(), - * appConfig, - * driver - * ]); - * await kernel.start(); - * - * // New (recommended): - * const kernel = new ObjectKernel(); - * kernel - * .use(new ObjectQLPlugin()) - * .use(new DriverPlugin(driver, 'memory')) - * .use(new AppManifestPlugin(appConfig)); - * await kernel.bootstrap(); - * ``` - */ -export class ObjectStackKernel { - public ql?: ObjectQL; // Will be set by ObjectQLPlugin or fallback initialization - private plugins: any[]; - - constructor(plugins: any[] = []) { - this.plugins = plugins; - - // Check if any plugin provides ObjectQL via type: 'objectql' - // This aligns with the manifest schema that supports objectql as a package type - const hasObjectQLPlugin = plugins.some(p => - p && typeof p === 'object' && p.type === 'objectql' - ); - - if (!hasObjectQLPlugin) { - // Backward compatibility: Initialize ObjectQL directly if no plugin provides it - console.warn('[Kernel] No ObjectQL plugin found, using default initialization. Consider using ObjectQLPlugin.'); - this.ql = new ObjectQL({ - env: process.env.NODE_ENV || 'development' - }); - } - } - - /** - * Ensure ObjectQL engine is initialized - * @throws Error if ObjectQL is not available - */ - private ensureObjectQL(): ObjectQL { - if (!this.ql) { - throw new Error('[Kernel] ObjectQL engine not initialized. Ensure ObjectQLPlugin is registered or kernel is properly initialized.'); - } - return this.ql; - } - - async start() { - console.log('[Kernel] Starting...'); - - // 0. Register Provided Plugins - for (const p of this.plugins) { - // Check if it is a Runtime Plugin (System Capability) - if ('onStart' in p || 'install' in p) { - console.log(`[Kernel] Loading Runtime Plugin: ${p.name}`); - if (p.install) await p.install({ engine: this }); - continue; - } - - // Otherwise treat as App Manifest - console.log(`[Kernel] Loading App Manifest: ${p.id || p.name}`); - SchemaRegistry.registerPlugin(p); - - // Register Objects from App/Plugin - if (p.objects) { - for (const obj of p.objects) { - SchemaRegistry.registerObject(obj); - console.log(`[Kernel] Registered Object: ${obj.name}`); - } - } - } - - // 1. Load Drivers (Default to Memory if none provided in plugins) - // TODO: Detect driver from plugins. For now, we still hard load memory driver if needed? - // In strict mode, user should pass driver in plugins array (DriverManifest). - // check if driver is registered - - // For Backwards Compat / Easy Dev, try dynamic import of memory driver if installed - try { - // @ts-ignore - const { InMemoryDriver } = await import('@objectstack/driver-memory'); - const driver = new InMemoryDriver(); - this.ensureObjectQL().registerDriver(driver); - } catch (e) { - // Ignore if not present - } - - // 2. Initialize Engine - await this.ensureObjectQL().init(); - - - // 3. Seed Data - await this.seed(); - - // 4. Start Runtime Plugins - for (const p of this.plugins) { - if (('onStart' in p) && typeof p.onStart === 'function') { - console.log(`[Kernel] Starting Plugin: ${p.name}`); - await p.onStart({ engine: this }); - } - } - } - - async seed() { - // If no driver registered yet, this might fail or wait. - // In real world, we wait for 'ready' event. - try { - // Mock System Table - try { - // We don't have SystemStatus defined in schema usually, skipping for general engine - // await this.ql.insert('SystemStatus', { status: 'OK', uptime: 0 }); - } catch {} - - // Iterate over all registered plugins/apps and check for 'data' property in manifest - - const plugins = SchemaRegistry.getRegisteredTypes(); // This returns types like 'plugin', 'app' - - // This is a bit hacky because we don't have a direct "getAllManifests" API exposed easily - // We will iterate known apps for now, or improve Registry API later. - // Actually, SchemaRegistry.listItems('app') returns the manifests! - - const apps = [...SchemaRegistry.listItems('app'), ...SchemaRegistry.listItems('plugin')]; - - for (const appItem of apps) { - const app = appItem as any; // Cast to access data prop safely - if (app.data && Array.isArray(app.data)) { - console.log(`[Kernel] Seeding data for ${app.name || app.id}...`); - for (const seed of app.data) { - try { - // Check if data exists - const existing = await this.ensureObjectQL().find(seed.object, { top: 1 }); - if (existing.length === 0) { - console.log(`[Kernel] Inserting ${seed.records.length} records into ${seed.object}`); - for (const record of seed.records) { - await this.ensureObjectQL().insert(seed.object, record); - } - } - } catch (e) { - console.warn(`[Kernel] Failed to seed ${seed.object}`, e); - } - } - } - } - - } catch(e) { - console.warn('Seed failed (driver might not be ready):', e); - } - } - - // Forward methods to ObjectQL - async find(objectName: string, query: any) { - this.ensureSchema(objectName); - const results = await this.ensureObjectQL().find(objectName, { top: 100 }); - return { value: results, count: results.length }; - } - - async get(objectName: string, id: string) { - this.ensureSchema(objectName); - // Find One - const results = await this.ensureObjectQL().find(objectName, { top: 1 }); // Mock implementation - return results[0]; - } - - async create(objectName: string, data: any) { - this.ensureSchema(objectName); - return this.ensureObjectQL().insert(objectName, data); - } - - async update(objectName: string, id: string, data: any) { - this.ensureSchema(objectName); - return this.ensureObjectQL().update(objectName, id, data); - } - - async delete(objectName: string, id: string) { - this.ensureSchema(objectName); - return this.ensureObjectQL().delete(objectName, id); - } - - // [New Methods for ObjectUI] - getMetadata(objectName: string) { - return this.ensureSchema(objectName); - } - - getView(objectName: string, viewType: 'list' | 'form' = 'list') { - const schema = this.ensureSchema(objectName); - - // Auto-Scaffold Default View - if (viewType === 'list') { - return { - type: 'datagrid', - title: `${schema.label || objectName} List`, - columns: Object.keys(schema.fields || {}).map(key => ({ - field: key, - label: schema.fields?.[key]?.label || key, - width: 150 - })), - actions: ['create', 'edit', 'delete'] - }; - } - return null; - } - - private ensureSchema(name: string): ServiceObject { - const schema = SchemaRegistry.getObject(name); - if (!schema) throw new Error(`Unknown object: ${name}`); - return schema; - } -} diff --git a/packages/runtime/src/objectql-plugin.ts b/packages/runtime/src/objectql-plugin.ts index c0404f144..480c0d520 100644 --- a/packages/runtime/src/objectql-plugin.ts +++ b/packages/runtime/src/objectql-plugin.ts @@ -1,5 +1,5 @@ import { ObjectQL } from '@objectstack/objectql'; -import { Plugin, PluginContext, RuntimePlugin, RuntimeContext } from './types.js'; +import { Plugin, PluginContext } from './types.js'; /** * ObjectQL Engine Plugin @@ -15,7 +15,7 @@ import { Plugin, PluginContext, RuntimePlugin, RuntimeContext } from './types.js * Services registered: * - 'objectql': ObjectQL engine instance */ -export class ObjectQLPlugin implements Plugin, RuntimePlugin { +export class ObjectQLPlugin implements Plugin { name = 'com.objectstack.engine.objectql'; type = 'objectql' as const; version = '1.0.0'; @@ -66,21 +66,6 @@ export class ObjectQLPlugin implements Plugin, RuntimePlugin { console.log('[ObjectQLPlugin] ObjectQL engine destroyed'); } - /** - * Legacy install method for backward compatibility - * @deprecated Use init/start lifecycle hooks instead - */ - async install(ctx: RuntimeContext) { - // Attach the ObjectQL engine to the kernel for backward compatibility - // Only works with ObjectStackKernel (legacy kernel) - if ('ql' in ctx.engine) { - (ctx.engine as any).ql = this.ql; - console.log('[ObjectQLPlugin] ObjectQL engine registered (legacy mode)'); - } else { - console.log('[ObjectQLPlugin] Legacy install called on new kernel - skipping ql property assignment'); - } - } - /** * Get the ObjectQL instance * @returns ObjectQL instance diff --git a/packages/runtime/src/protocol.ts b/packages/runtime/src/protocol.ts index 23f108184..a3ba31efd 100644 --- a/packages/runtime/src/protocol.ts +++ b/packages/runtime/src/protocol.ts @@ -1,5 +1,4 @@ import { SchemaRegistry, ObjectQL } from '@objectstack/objectql'; -import { ObjectStackKernel } from './kernel.js'; import { ObjectKernel } from './mini-kernel.js'; export interface ApiRequest { @@ -9,39 +8,27 @@ export interface ApiRequest { } export class ObjectStackRuntimeProtocol { - private engine: ObjectStackKernel | ObjectKernel; - private legacyKernel?: ObjectStackKernel; + private engine: ObjectKernel; private objectql?: ObjectQL; - constructor(engine: ObjectStackKernel | ObjectKernel) { + constructor(engine: ObjectKernel) { this.engine = engine; - // Detect which kernel type we're using - if (engine instanceof ObjectStackKernel) { - this.legacyKernel = engine; - } else if (engine instanceof ObjectKernel) { - // Get ObjectQL service from kernel - will be validated when needed - try { - this.objectql = engine.getService('objectql'); - } catch (e) { - // Don't fail construction - some protocol methods may still work - // Error will be thrown when getObjectQL() is called - console.warn('[Protocol] ObjectQL service not found in kernel - data operations will fail'); - } + // Get ObjectQL service from kernel - will be validated when needed + try { + this.objectql = engine.getService('objectql'); + } catch (e) { + // Don't fail construction - some protocol methods may still work + // Error will be thrown when getObjectQL() is called + console.warn('[Protocol] ObjectQL service not found in kernel - data operations will fail'); } } /** - * Get ObjectQL instance - works with both kernel types + * Get ObjectQL instance * @throws Error if ObjectQL is not available */ private getObjectQL(): ObjectQL { - if (this.legacyKernel) { - if (!this.legacyKernel.ql) { - throw new Error('[Protocol] ObjectQL not initialized in legacy kernel'); - } - return this.legacyKernel.ql; - } if (!this.objectql) { throw new Error('[Protocol] ObjectQL service not available in kernel. Ensure ObjectQLPlugin is registered and initialized.'); } @@ -126,14 +113,7 @@ export class ObjectStackRuntimeProtocol { // 5. UI: View Definition getUiView(objectName: string, type: 'list' | 'form') { - // Use legacy kernel method if available - if (this.legacyKernel) { - const view = this.legacyKernel.getView(objectName, type); - if (!view) throw new Error('View not generated'); - return view; - } - - // Otherwise generate view from schema + // Generate view from schema const schema = SchemaRegistry.getObject(objectName); if (!schema) throw new Error(`Unknown object: ${objectName}`); @@ -154,9 +134,6 @@ export class ObjectStackRuntimeProtocol { // 6. Data: Find async findData(objectName: string, query: any) { - if (this.legacyKernel) { - return await this.legacyKernel.find(objectName, query); - } const ql = this.getObjectQL(); const results = await ql.find(objectName, query || { top: 100 }); return { value: results, count: results.length }; @@ -164,9 +141,6 @@ export class ObjectStackRuntimeProtocol { // 7. Data: Query (Advanced AST) async queryData(objectName: string, body: any) { - if (this.legacyKernel) { - return await this.legacyKernel.find(objectName, body); - } const ql = this.getObjectQL(); const results = await ql.find(objectName, body || { top: 100 }); return { value: results, count: results.length }; @@ -174,9 +148,6 @@ export class ObjectStackRuntimeProtocol { // 8. Data: Get async getData(objectName: string, id: string) { - if (this.legacyKernel) { - return await this.legacyKernel.get(objectName, id); - } const ql = this.getObjectQL(); // TODO: Implement proper ID-based lookup once ObjectQL supports it // For now, this is a limitation of the current ObjectQL API @@ -186,27 +157,18 @@ export class ObjectStackRuntimeProtocol { // 9. Data: Create async createData(objectName: string, body: any) { - if (this.legacyKernel) { - return await this.legacyKernel.create(objectName, body); - } const ql = this.getObjectQL(); return await ql.insert(objectName, body); } // 10. Data: Update async updateData(objectName: string, id: string, body: any) { - if (this.legacyKernel) { - return await this.legacyKernel.update(objectName, id, body); - } const ql = this.getObjectQL(); return await ql.update(objectName, id, body); } // 11. Data: Delete async deleteData(objectName: string, id: string) { - if (this.legacyKernel) { - return await this.legacyKernel.delete(objectName, id); - } const ql = this.getObjectQL(); return await ql.delete(objectName, id); } diff --git a/packages/runtime/src/types.ts b/packages/runtime/src/types.ts index f292f2c41..d95fd3511 100644 --- a/packages/runtime/src/types.ts +++ b/packages/runtime/src/types.ts @@ -1,24 +1,5 @@ -import { ObjectStackKernel } from './kernel.js'; import { ObjectKernel } from './mini-kernel.js'; -/** - * Legacy RuntimeContext (Backward Compatibility) - * @deprecated Use PluginContext instead - */ -export interface RuntimeContext { - engine: ObjectStackKernel | ObjectKernel; -} - -/** - * Legacy RuntimePlugin (Backward Compatibility) - * @deprecated Use Plugin interface instead - */ -export interface RuntimePlugin { - name: string; - install?: (ctx: RuntimeContext) => void | Promise; - onStart?: (ctx: RuntimeContext) => void | Promise; -} - /** * PluginContext - Runtime context available to plugins * @@ -67,7 +48,7 @@ export interface PluginContext { * Get the kernel instance (for advanced use cases) * @returns Kernel instance */ - getKernel?(): ObjectStackKernel | ObjectKernel; + getKernel?(): ObjectKernel; } /** diff --git a/test-objectql-plugin.ts b/test-objectql-plugin.ts index d6d9c7461..335eab288 100644 --- a/test-objectql-plugin.ts +++ b/test-objectql-plugin.ts @@ -3,40 +3,48 @@ * * This script validates: * 1. Plugin-based ObjectQL registration works - * 2. Backward compatibility (without plugin) works - * 3. Custom ObjectQL instance works + * 2. Custom ObjectQL instance works + * 3. Multiple plugins with ObjectQL work */ -import { ObjectStackKernel, ObjectQLPlugin, ObjectQL, SchemaRegistry } from '../packages/runtime/src'; +import { ObjectKernel, ObjectQLPlugin, ObjectQL, SchemaRegistry } from '../packages/runtime/src'; async function testPluginBasedRegistration() { console.log('\n=== Test 1: Plugin-based ObjectQL Registration ==='); - const kernel = new ObjectStackKernel([ - new ObjectQLPlugin() - ]); + const kernel = new ObjectKernel(); + kernel.use(new ObjectQLPlugin()); - // Verify ObjectQL is set - if (!kernel.ql) { - throw new Error('FAILED: ObjectQL not set via plugin'); - } + await kernel.bootstrap(); - console.log('✅ ObjectQL registered via plugin'); - console.log('ObjectQL instance:', kernel.ql.constructor.name); + // Verify ObjectQL is available as a service + try { + const ql = kernel.getService('objectql'); + console.log('✅ ObjectQL registered via plugin'); + console.log('ObjectQL instance:', ql.constructor.name); + } catch (e) { + throw new Error('FAILED: ObjectQL service not found'); + } } -async function testBackwardCompatibility() { - console.log('\n=== Test 2: Backward Compatibility (No Plugin) ==='); +async function testMissingObjectQL() { + console.log('\n=== Test 2: Missing ObjectQL Service ==='); - const kernel = new ObjectStackKernel([]); + const kernel = new ObjectKernel(); - // Verify ObjectQL is auto-initialized - if (!kernel.ql) { - throw new Error('FAILED: ObjectQL not auto-initialized'); - } + await kernel.bootstrap(); - console.log('✅ ObjectQL auto-initialized for backward compatibility'); - console.log('ObjectQL instance:', kernel.ql.constructor.name); + // Verify ObjectQL throws error when not registered + try { + kernel.getService('objectql'); + throw new Error('FAILED: Should have thrown error for missing ObjectQL'); + } catch (e: any) { + if (e.message.includes('Service not found')) { + console.log('✅ Correctly throws error when ObjectQL service is not registered'); + } else { + throw e; + } + } } async function testCustomObjectQL() { @@ -53,20 +61,19 @@ async function testCustomObjectQL() { // Mark this as a custom instance customInstances.set(customQL, 'custom-instance'); - const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(customQL) - ]); + const kernel = new ObjectKernel(); + kernel.use(new ObjectQLPlugin(customQL)); + + await kernel.bootstrap(); // Verify the custom instance is used - if (!kernel.ql) { - throw new Error('FAILED: ObjectQL not set'); - } + const ql = kernel.getService('objectql'); - if (!customInstances.has(kernel.ql)) { + if (!customInstances.has(ql)) { throw new Error('FAILED: Custom ObjectQL instance not used'); } - const marker = customInstances.get(kernel.ql); + const marker = customInstances.get(ql); if (marker !== 'custom-instance') { throw new Error('FAILED: Custom ObjectQL instance marker mismatch'); } @@ -78,26 +85,23 @@ async function testCustomObjectQL() { async function testMultiplePlugins() { console.log('\n=== Test 4: Multiple Plugins with ObjectQL ==='); - // Mock driver - const mockDriver = { - name: 'mock-driver', - version: '1.0.0', - capabilities: {}, - async connect() {}, - async disconnect() {}, - async find() { return []; }, - async findOne() { return null; }, - async create() { return {}; }, - async update() { return {}; }, - async delete() { return {}; } + // Mock plugin + const mockPlugin = { + name: 'mock-plugin', + async init(ctx: any) { + console.log(' Mock plugin initialized'); + } }; - const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(), - mockDriver - ]); + const kernel = new ObjectKernel(); + kernel + .use(new ObjectQLPlugin()) + .use(mockPlugin); + + await kernel.bootstrap(); - if (!kernel.ql) { + const ql = kernel.getService('objectql'); + if (!ql) { throw new Error('FAILED: ObjectQL not set'); } @@ -109,7 +113,7 @@ async function runAllTests() { try { await testPluginBasedRegistration(); - await testBackwardCompatibility(); + await testMissingObjectQL(); await testCustomObjectQL(); await testMultiplePlugins(); From 581f2a8667b0d9265ba7350e4994d16a527a2694 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 03:49:12 +0000 Subject: [PATCH 3/7] Update OBJECTQL_PLUGIN_QUICKSTART.md to use new ObjectKernel architecture Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- OBJECTQL_PLUGIN_QUICKSTART.md | 104 +++++++++++++++------------------- 1 file changed, 47 insertions(+), 57 deletions(-) diff --git a/OBJECTQL_PLUGIN_QUICKSTART.md b/OBJECTQL_PLUGIN_QUICKSTART.md index 7d0df3dcb..f9b82dc29 100644 --- a/OBJECTQL_PLUGIN_QUICKSTART.md +++ b/OBJECTQL_PLUGIN_QUICKSTART.md @@ -11,20 +11,19 @@ npm install @objectstack/runtime ### Default ObjectQL (Recommended) ```typescript -import { ObjectStackKernel, ObjectQLPlugin } from '@objectstack/runtime'; +import { ObjectKernel, ObjectQLPlugin } from '@objectstack/runtime'; -const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(), - // ... other plugins -]); +const kernel = new ObjectKernel(); +kernel.use(new ObjectQLPlugin()); +// ... other plugins -await kernel.start(); +await kernel.bootstrap(); ``` ### Custom ObjectQL Instance ```typescript -import { ObjectStackKernel, ObjectQLPlugin, ObjectQL } from '@objectstack/runtime'; +import { ObjectKernel, ObjectQLPlugin, ObjectQL } from '@objectstack/runtime'; // Create custom instance const customQL = new ObjectQL({ @@ -38,21 +37,11 @@ customQL.registerHook('beforeInsert', async (ctx) => { }); // Use in kernel -const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(customQL), - // ... other plugins -]); +const kernel = new ObjectKernel(); +kernel.use(new ObjectQLPlugin(customQL)); +// ... other plugins -await kernel.start(); -``` - -### Backward Compatible (Legacy) - -```typescript -// Still works without ObjectQLPlugin, but shows warning -const kernel = new ObjectStackKernel([ - // ... plugins -]); +await kernel.bootstrap(); ``` ## API Reference @@ -85,20 +74,21 @@ new ObjectQLPlugin(undefined, { env: 'prod', debug: true }) ## Migration Guide -### From Hardcoded to Plugin-Based +### From Array-Based to Chaining Pattern **Before:** ```typescript -const kernel = new ObjectStackKernel([appConfig, driver]); +const kernel = new ObjectKernel([appConfig, driver]); ``` **After:** ```typescript -const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(), // Add this line - appConfig, - driver -]); +const kernel = new ObjectKernel(); +kernel.use(new ObjectQLPlugin()); // Add this line +kernel.use(appConfig); +kernel.use(driver); + +await kernel.bootstrap(); ``` ## Common Patterns @@ -106,14 +96,15 @@ const kernel = new ObjectStackKernel([ ### Testing with Mock ObjectQL ```typescript -import { ObjectQLPlugin } from '@objectstack/runtime'; +import { ObjectKernel, ObjectQLPlugin } from '@objectstack/runtime'; import { MockObjectQL } from './mocks'; const mockQL = new MockObjectQL(); -const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(mockQL), - // ... test config -]); +const kernel = new ObjectKernel(); +kernel.use(new ObjectQLPlugin(mockQL)); +// ... test config + +await kernel.bootstrap(); ``` ### Multiple Environments @@ -121,22 +112,25 @@ const kernel = new ObjectStackKernel([ ```typescript // Production const prodQL = new ObjectQL({ env: 'production', cache: true }); -const prodKernel = new ObjectStackKernel([ - new ObjectQLPlugin(prodQL), - // ... production plugins -]); +const prodKernel = new ObjectKernel(); +prodKernel.use(new ObjectQLPlugin(prodQL)); +// ... production plugins + +await prodKernel.bootstrap(); // Development -const devKernel = new ObjectStackKernel([ - new ObjectQLPlugin(undefined, { env: 'development', debug: true }), - // ... dev plugins -]); +const devKernel = new ObjectKernel(); +devKernel.use(new ObjectQLPlugin(undefined, { env: 'development', debug: true })); +// ... dev plugins + +await devKernel.bootstrap(); ``` ### Custom ObjectQL from Separate Project ```typescript // Your custom implementation +import { ObjectKernel, ObjectQLPlugin } from '@objectstack/runtime'; import { MyCustomObjectQL } from '@mycompany/custom-objectql'; const customQL = new MyCustomObjectQL({ @@ -144,29 +138,25 @@ const customQL = new MyCustomObjectQL({ // custom options }); -const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(customQL), - // ... other plugins -]); +const kernel = new ObjectKernel(); +kernel.use(new ObjectQLPlugin(customQL)); +// ... other plugins + +await kernel.bootstrap(); ``` ## Troubleshooting ### Error: "ObjectQL engine not initialized" -This means the kernel tried to use ObjectQL before it was set up. Make sure: -1. You include `ObjectQLPlugin` in your plugins array, OR -2. The kernel has backward compatibility enabled - -### Warning: "No ObjectQL plugin found..." - -This is a deprecation warning. Your code will work, but consider migrating to: +This means the kernel tried to use ObjectQL before it was set up. Make sure you register the `ObjectQLPlugin`: ```typescript -new ObjectStackKernel([ - new ObjectQLPlugin(), // Add this - // ... other plugins -]); +const kernel = new ObjectKernel(); +kernel.use(new ObjectQLPlugin()); // Add this +// ... other plugins + +await kernel.bootstrap(); ``` ### Warning: "Both ql and hostContext provided..." @@ -202,7 +192,7 @@ The plugin sets `type = 'objectql'` which aligns with the manifest schema that s The kernel's `ql` property is typed as optional: ```typescript -export class ObjectStackKernel { +export class ObjectKernel { public ql?: ObjectQL; private ensureObjectQL(): ObjectQL { From c940669bac46e259e83035c77e9780e20faeeef5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 03:51:10 +0000 Subject: [PATCH 4/7] Remove all ObjectStackKernel references from MiniKernel documentation Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- MINI_KERNEL_ARCHITECTURE.md | 13 +------ MINI_KERNEL_GUIDE.md | 18 +--------- MINI_KERNEL_IMPLEMENTATION.md | 34 +----------------- MINI_KERNEL_INDEX.md | 12 +------ MINI_KERNEL_SUMMARY.md | 68 +++++------------------------------ packages/runtime/README.md | 35 ------------------ 6 files changed, 12 insertions(+), 168 deletions(-) diff --git a/MINI_KERNEL_ARCHITECTURE.md b/MINI_KERNEL_ARCHITECTURE.md index 7dc419f68..e1ae122f9 100644 --- a/MINI_KERNEL_ARCHITECTURE.md +++ b/MINI_KERNEL_ARCHITECTURE.md @@ -232,18 +232,7 @@ Plugin A Plugin B Plugin C ## 6. ObjectQL 插件化 (ObjectQL as Plugin) ``` -Before (Hardcoded): -┌─────────────────────┐ -│ ObjectStackKernel │ -│ │ -│ ┌───────────────┐ │ -│ │ ObjectQL │ │ ← 硬编码在 Kernel 中 -│ │ (Hardcoded) │ │ -│ └───────────────┘ │ -│ │ -└─────────────────────┘ - -After (Plugin-based): +Plugin-based Architecture: ┌─────────────────────┐ │ ObjectKernel │ │ (MiniKernel) │ diff --git a/MINI_KERNEL_GUIDE.md b/MINI_KERNEL_GUIDE.md index e018ba24c..f1ffa8a4a 100644 --- a/MINI_KERNEL_GUIDE.md +++ b/MINI_KERNEL_GUIDE.md @@ -264,23 +264,7 @@ if (process.env.ENABLE_API === 'true') { } ``` -## Migration from Old Kernel - -### Before (ObjectStackKernel) - -```typescript -import { ObjectStackKernel, ObjectQLPlugin } from '@objectstack/runtime'; - -const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(), - appManifest, - driver -]); - -await kernel.start(); -``` - -### After (ObjectKernel) +## Usage ```typescript import { ObjectKernel, ObjectQLPlugin, DriverPlugin } from '@objectstack/runtime'; diff --git a/MINI_KERNEL_IMPLEMENTATION.md b/MINI_KERNEL_IMPLEMENTATION.md index 82d79df61..4af868c18 100644 --- a/MINI_KERNEL_IMPLEMENTATION.md +++ b/MINI_KERNEL_IMPLEMENTATION.md @@ -132,11 +132,7 @@ kernel.use(new DriverPlugin(memoryDriver, 'memory')); - 插件可以独立测试 - 依赖注入简化测试 -### 4. 向后兼容 -- 保留 `ObjectStackKernel` 和旧的 `RuntimePlugin` 接口 -- 平滑迁移路径 -- 不影响现有代码 ## 使用示例 (Usage Examples) @@ -202,7 +198,6 @@ packages/runtime/src/ ├── types.ts # Plugin, PluginContext 接口 ├── objectql-plugin.ts # ObjectQL 插件 ├── driver-plugin.ts # Driver 插件 -├── kernel.ts # 原有 ObjectStackKernel (保持兼容) ├── protocol.ts # Runtime Protocol └── index.ts # 导出 @@ -211,34 +206,7 @@ examples/mini-kernel-example.ts # 示例代码 test-mini-kernel.ts # 测试套件 ``` -## 迁移指南 (Migration Guide) - -### 从旧 Kernel 迁移 - -**Before**: -```typescript -import { ObjectStackKernel, ObjectQLPlugin } from '@objectstack/runtime'; - -const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(), - appManifest -]); - -await kernel.start(); -``` - -**After**: -```typescript -import { ObjectKernel, ObjectQLPlugin } from '@objectstack/runtime'; - -const kernel = new ObjectKernel(); - -kernel - .use(new ObjectQLPlugin()) - .use(appManifestPlugin); - -await kernel.bootstrap(); -``` +## 使用指南 (Usage Guide) ### 创建新插件 diff --git a/MINI_KERNEL_INDEX.md b/MINI_KERNEL_INDEX.md index 847ca0616..acc6ef483 100644 --- a/MINI_KERNEL_INDEX.md +++ b/MINI_KERNEL_INDEX.md @@ -64,18 +64,8 @@ const objectql = kernel.getService('objectql'); - ✅ **依赖解析**: 自动拓扑排序 - ✅ **向后兼容**: 保留旧 API -## 🔄 迁移路径 +## 🔄 使用示例 -### 旧架构 -```typescript -const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(), - appManifest -]); -await kernel.start(); -``` - -### 新架构 ```typescript const kernel = new ObjectKernel(); kernel.use(new ObjectQLPlugin()); diff --git a/MINI_KERNEL_SUMMARY.md b/MINI_KERNEL_SUMMARY.md index f2ed5982e..020a93289 100644 --- a/MINI_KERNEL_SUMMARY.md +++ b/MINI_KERNEL_SUMMARY.md @@ -6,28 +6,7 @@ **核心原则**: 像 Linux Kernel 一样,将核心功能剥离到最小,所有业务逻辑作为插件加载。 -## 架构对比 - -### 改造前 (Before) - -```typescript -// ObjectQL 硬编码在 Kernel 中 -class ObjectStackKernel { - private ql: ObjectQL; // ← 硬编码 - - constructor(plugins) { - this.ql = new ObjectQL(); // ← 无法替换 - } -} -``` - -**问题:** -- ❌ ObjectQL 硬编码,无法替换 -- ❌ 插件之间无法通信 -- ❌ 没有标准的生命周期 -- ❌ 测试困难,无法 Mock - -### 改造后 (After) +## 架构特点 ```typescript // ObjectQL 成为可插拔的服务 @@ -329,7 +308,7 @@ async trigger(name, ...args) { node test-mini-kernel.js ``` -## 迁移指南 +## 使用指南 ### 步骤 1: 安装依赖 @@ -337,21 +316,8 @@ node test-mini-kernel.js npm install @objectstack/runtime ``` -### 步骤 2: 更新代码 +### 步骤 2: 编写代码 -**Before:** -```typescript -import { ObjectStackKernel, ObjectQLPlugin } from '@objectstack/runtime'; - -const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(), - appManifest -]); - -await kernel.start(); -``` - -**After:** ```typescript import { ObjectKernel, ObjectQLPlugin } from '@objectstack/runtime'; @@ -370,37 +336,19 @@ await kernel.bootstrap(); npm test ``` -## 向后兼容性 - -✅ **保持兼容**: -- `ObjectStackKernel` 保留 -- `RuntimePlugin` 接口保留 -- 旧代码继续工作 -🎯 **平滑迁移**: -- 新旧代码可共存 -- 渐进式迁移 -- 无破坏性变更 -## 性能对比 +## 性能特点 ### 启动时间 -| 架构 | 插件数 | 启动时间 | -|------|--------|----------| -| 旧架构 | 5 | ~200ms | -| 新架构 | 5 | ~220ms | - -**结论**: 性能几乎一致 (+10% overhead for DI) +- 5个插件: ~220ms +- 依赖解析: O(V+E) 时间复杂度 ### 内存占用 -| 架构 | 内存 | -|------|------| -| 旧架构 | ~50MB | -| 新架构 | ~52MB | - -**结论**: 内存增加可忽略 (+4%) +- 基础内存: ~52MB +- 服务注册表: O(1) 查找性能 ## 未来规划 diff --git a/packages/runtime/README.md b/packages/runtime/README.md index caacde707..91be75893 100644 --- a/packages/runtime/README.md +++ b/packages/runtime/README.md @@ -164,37 +164,6 @@ See the `examples/` directory for complete examples: - `examples/custom-objectql-example.ts` - Custom ObjectQL instance - `test-mini-kernel.ts` - Comprehensive test suite -## Migration Guide - -### From ObjectStackKernel to ObjectKernel - -**Before (Legacy):** -```typescript -import { ObjectStackKernel, ObjectQLPlugin } from '@objectstack/runtime'; - -const kernel = new ObjectStackKernel([ - new ObjectQLPlugin(), - appConfig, - driver -]); - -await kernel.start(); -``` - -**After (Recommended):** -```typescript -import { ObjectKernel, ObjectQLPlugin, DriverPlugin, AppManifestPlugin } from '@objectstack/runtime'; - -const kernel = new ObjectKernel(); - -kernel - .use(new ObjectQLPlugin()) - .use(new DriverPlugin(driver, 'memory')) - .use(new AppManifestPlugin(appConfig)); - -await kernel.bootstrap(); -``` - ## Benefits of MiniKernel 1. **True Modularity**: Each plugin is independent and reusable @@ -218,10 +187,6 @@ await kernel.bootstrap(); - [MiniKernel Architecture](../../MINI_KERNEL_ARCHITECTURE.md) - Architecture diagrams and flows - [MiniKernel Implementation](../../MINI_KERNEL_IMPLEMENTATION.md) - Implementation details -## Legacy Support - -The `ObjectStackKernel` is still available for backward compatibility but is deprecated. New projects should use `ObjectKernel`. - ## License Apache-2.0 From e677937d99e269d666e18d98509a85e70306c1d5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 03:55:24 +0000 Subject: [PATCH 5/7] Update QUICKSTART.md to use new ObjectKernel API Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- examples/msw-react-crud/QUICKSTART.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/msw-react-crud/QUICKSTART.md b/examples/msw-react-crud/QUICKSTART.md index da4d802b9..15a92583e 100644 --- a/examples/msw-react-crud/QUICKSTART.md +++ b/examples/msw-react-crud/QUICKSTART.md @@ -72,9 +72,10 @@ Now just **3 lines** with auto-mocking: ```typescript // src/mocks/browser.ts - NEW WAY -const mswPlugin = new MSWPlugin({ baseUrl: '/api/v1' }); -const runtime = new ObjectStackKernel([appConfig, mswPlugin]); -await runtime.start(); // Auto-mocks ALL endpoints! +const kernel = new ObjectKernel(); +kernel.use(new AppManifestPlugin(appConfig)); +kernel.use(new MSWPlugin({ baseUrl: '/api/v1' })); +await kernel.bootstrap(); // Auto-mocks ALL endpoints! ``` ## 📦 How It Works @@ -140,10 +141,13 @@ const customHandlers = [ ) ]; -const mswPlugin = new MSWPlugin({ +const kernel = new ObjectKernel(); +kernel.use(new AppManifestPlugin(appConfig)); +kernel.use(new MSWPlugin({ customHandlers, // Add your custom handlers baseUrl: '/api/v1' -}); +})); +await kernel.bootstrap(); ``` ## Troubleshooting From bfe329f6ce479e7d8a577a2f1a51471a68ef3165 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 03:59:53 +0000 Subject: [PATCH 6/7] Update documentation files and fix mini-kernel build Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- packages/runtime/src/mini-kernel.ts | 60 +++++++---------------------- 1 file changed, 13 insertions(+), 47 deletions(-) diff --git a/packages/runtime/src/mini-kernel.ts b/packages/runtime/src/mini-kernel.ts index c103ffd66..3e220bd6c 100644 --- a/packages/runtime/src/mini-kernel.ts +++ b/packages/runtime/src/mini-kernel.ts @@ -1,4 +1,4 @@ -import { Plugin, PluginContext, RuntimePlugin, RuntimeContext } from './types.js'; +import { Plugin, PluginContext } from './types.js'; import { SchemaRegistry, ObjectQL } from '@objectstack/objectql'; /** @@ -16,7 +16,7 @@ import { SchemaRegistry, ObjectQL } from '@objectstack/objectql'; * - Plugins are loaded as equal building blocks */ export class ObjectKernel { - private plugins: Map = new Map(); + private plugins: Map = new Map(); private services: Map = new Map(); private hooks: Map void | Promise>> = new Map(); private state: 'idle' | 'initializing' | 'running' | 'stopped' = 'idle'; @@ -59,7 +59,7 @@ export class ObjectKernel { * Register a plugin * @param plugin - Plugin instance */ - use(plugin: Plugin | RuntimePlugin) { + use(plugin: Plugin) { if (this.state !== 'idle') { throw new Error('[Kernel] Cannot register plugins after bootstrap has started'); } @@ -77,8 +77,8 @@ export class ObjectKernel { * Resolve plugin dependencies using topological sort * @returns Ordered list of plugins */ - private resolveDependencies(): (Plugin | RuntimePlugin)[] { - const resolved: (Plugin | RuntimePlugin)[] = []; + private resolveDependencies(): Plugin[] { + const resolved: Plugin[] = []; const visited = new Set(); const visiting = new Set(); @@ -96,8 +96,8 @@ export class ObjectKernel { visiting.add(pluginName); - // Visit dependencies first (for new Plugin interface) - const deps = this.isNewPlugin(plugin) ? plugin.dependencies || [] : []; + // Visit dependencies first + const deps = plugin.dependencies || []; for (const dep of deps) { if (!this.plugins.has(dep)) { throw new Error(`[Kernel] Dependency '${dep}' not found for plugin '${pluginName}'`); @@ -118,13 +118,6 @@ export class ObjectKernel { return resolved; } - /** - * Type guard to check if plugin uses new interface - */ - private isNewPlugin(plugin: Plugin | RuntimePlugin): plugin is Plugin { - return 'init' in plugin; - } - /** * Bootstrap the kernel * 1. Resolve dependencies (topological sort) @@ -146,44 +139,17 @@ export class ObjectKernel { // Phase 1: Init - Plugins register services this.context.logger.log('[Kernel] Phase 1: Init plugins...'); for (const plugin of orderedPlugins) { - if (this.isNewPlugin(plugin)) { - this.context.logger.log(`[Kernel] Init: ${plugin.name}`); - await plugin.init(this.context); - } else { - // Legacy RuntimePlugin support - this.context.logger.log(`[Kernel] Init (legacy): ${plugin.name}`); - if (plugin.install) { - await plugin.install({ engine: this as any }); - } - // Also handle old manifest-style plugins - if ('objects' in plugin) { - SchemaRegistry.registerPlugin(plugin as any); - const objects = (plugin as any).objects; - if (objects) { - for (const obj of objects) { - SchemaRegistry.registerObject(obj); - this.context.logger.log(`[Kernel] Registered Object: ${obj.name}`); - } - } - } - } + this.context.logger.log(`[Kernel] Init: ${plugin.name}`); + await plugin.init(this.context); } // Phase 2: Start - Plugins execute business logic this.context.logger.log('[Kernel] Phase 2: Start plugins...'); this.state = 'running'; for (const plugin of orderedPlugins) { - if (this.isNewPlugin(plugin)) { - if (plugin.start) { - this.context.logger.log(`[Kernel] Start: ${plugin.name}`); - await plugin.start(this.context); - } - } else { - // Legacy RuntimePlugin support - if (plugin.onStart) { - this.context.logger.log(`[Kernel] Start (legacy): ${plugin.name}`); - await plugin.onStart({ engine: this as any }); - } + if (plugin.start) { + this.context.logger.log(`[Kernel] Start: ${plugin.name}`); + await plugin.start(this.context); } } @@ -208,7 +174,7 @@ export class ObjectKernel { const orderedPlugins = Array.from(this.plugins.values()).reverse(); for (const plugin of orderedPlugins) { - if (this.isNewPlugin(plugin) && plugin.destroy) { + if (plugin.destroy) { this.context.logger.log(`[Kernel] Destroy: ${plugin.name}`); await plugin.destroy(); } From bd67633a982408a20d99f0123b53dbfb587a27fe Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 28 Jan 2026 04:04:20 +0000 Subject: [PATCH 7/7] Remove all ObjectStackKernel references from plugins Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com> --- .../plugin-hono-server/src/hono-plugin.ts | 111 +----------------- packages/plugin-msw/src/msw-plugin.ts | 35 +----- 2 files changed, 5 insertions(+), 141 deletions(-) diff --git a/packages/plugin-hono-server/src/hono-plugin.ts b/packages/plugin-hono-server/src/hono-plugin.ts index 261ce5220..26d3e083d 100644 --- a/packages/plugin-hono-server/src/hono-plugin.ts +++ b/packages/plugin-hono-server/src/hono-plugin.ts @@ -6,8 +6,6 @@ import { logger } from 'hono/logger'; import { Plugin, PluginContext, - RuntimePlugin, - RuntimeContext, ObjectStackRuntimeProtocol } from '@objectstack/runtime'; @@ -30,7 +28,7 @@ export interface HonoPluginOptions { * const server = new HonoServerPlugin({ port: 3000 }); * kernel.use(server); */ -export class HonoServerPlugin implements Plugin, RuntimePlugin { +export class HonoServerPlugin implements Plugin { name = 'com.objectstack.server.hono'; version = '1.0.0'; @@ -116,111 +114,4 @@ export class HonoServerPlugin implements Plugin, RuntimePlugin { console.log('[HonoServerPlugin] Server stopped'); } } - - /** - * Legacy install method for backward compatibility - * @deprecated Use init/start lifecycle hooks instead - */ - install(ctx: RuntimeContext) { - const { engine } = ctx; - const protocol = new ObjectStackRuntimeProtocol(engine); - - // --- Bind Protocol to Hono --- - - // 1. Discovery - this.app.get('/api/v1', (c) => c.json(protocol.getDiscovery())); - - // 2. Meta - this.app.get('/api/v1/meta', (c) => c.json(protocol.getMetaTypes())); - this.app.get('/api/v1/meta/:type', (c) => c.json(protocol.getMetaItems(c.req.param('type')))); - this.app.get('/api/v1/meta/:type/:name', (c) => { - try { - return c.json(protocol.getMetaItem(c.req.param('type'), c.req.param('name'))); - } catch (e: any) { - return c.json({ error: e.message }, 404); - } - }); - - // 3. Data - this.app.get('/api/v1/data/:object', async (c) => { - try { - const result = await protocol.findData(c.req.param('object'), c.req.query()); - return c.json(result); - } catch (e: any) { - return c.json({ error: e.message }, 404); - } - }); - - this.app.get('/api/v1/data/:object/:id', async (c) => { - try { - const result = await protocol.getData(c.req.param('object'), c.req.param('id')); - return c.json(result); - } catch (e: any) { - return c.json({ error: e.message }, 404); - } - }); - - this.app.post('/api/v1/data/:object', async (c) => { - try { - const body = await c.req.json(); - const result = await protocol.createData(c.req.param('object'), body); - return c.json(result, 201); - } catch (e: any) { - return c.json({ error: e.message }, 400); - } - }); - - this.app.patch('/api/v1/data/:object/:id', async (c) => { - try { - const body = await c.req.json(); - const result = await protocol.updateData(c.req.param('object'), c.req.param('id'), body); - return c.json(result); - } catch (e: any) { - return c.json({ error: e.message }, 400); - } - }); - - this.app.delete('/api/v1/data/:object/:id', async (c) => { - try { - const result = await protocol.deleteData(c.req.param('object'), c.req.param('id')); - return c.json(result); - } catch (e: any) { - return c.json({ error: e.message }, 400); - } - }); - - // 4. UI Protocol - this.app.get('/api/v1/ui/view/:object', (c) => { - try { - // @ts-ignore - const view = protocol.getUiView(c.req.param('object'), c.req.query('type') || 'list'); - return c.json(view); - } catch (e: any) { - return c.json({ error: e.message }, 404); - } - }); - - // Static Files - if (this.options.staticRoot) { - this.app.get('/', serveStatic({ root: this.options.staticRoot, path: 'index.html' })); - this.app.get('/*', serveStatic({ root: this.options.staticRoot })); - } - - console.log(`[HonoPlugin] Installed routes and middleware.`); - } - - /** - * Legacy onStart method for backward compatibility - * @deprecated Use start lifecycle hook instead - */ - async onStart(ctx: RuntimeContext) { - const port = this.options.port; - console.log(`[HonoPlugin] Starting server...`); - console.log(`✅ Server is running on http://localhost:${port}`); - - serve({ - fetch: this.app.fetch, - port - }); - } } diff --git a/packages/plugin-msw/src/msw-plugin.ts b/packages/plugin-msw/src/msw-plugin.ts index c4f6182b4..6730175bc 100644 --- a/packages/plugin-msw/src/msw-plugin.ts +++ b/packages/plugin-msw/src/msw-plugin.ts @@ -1,8 +1,6 @@ import { http, HttpResponse } from 'msw'; import { setupWorker } from 'msw/browser'; import { - RuntimePlugin, - RuntimeContext, Plugin, PluginContext, ObjectStackRuntimeProtocol, @@ -156,8 +154,6 @@ export class ObjectStackServer { * This plugin enables Mock Service Worker integration for testing and development. * It automatically mocks API endpoints using the ObjectStack runtime protocol. * - * Supports both legacy RuntimePlugin and new Plugin interfaces. - * * @example * ```typescript * import { MSWPlugin } from '@objectstack/plugin-msw'; @@ -170,7 +166,7 @@ export class ObjectStackServer { * })); * ``` */ -export class MSWPlugin implements Plugin, RuntimePlugin { +export class MSWPlugin implements Plugin { name = 'com.objectstack.plugin.msw'; version = '1.0.0'; @@ -189,7 +185,7 @@ export class MSWPlugin implements Plugin, RuntimePlugin { } /** - * New Plugin interface - init phase + * Init phase */ async init(ctx: PluginContext) { // Protocol will be created in start phase @@ -197,7 +193,7 @@ export class MSWPlugin implements Plugin, RuntimePlugin { } /** - * New Plugin interface - start phase + * Start phase */ async start(ctx: PluginContext) { // Get the kernel and create protocol @@ -213,35 +209,12 @@ export class MSWPlugin implements Plugin, RuntimePlugin { } /** - * New Plugin interface - destroy phase + * Destroy phase */ async destroy() { await this.stopWorker(); } - /** - * Legacy RuntimePlugin interface - install - */ - install(ctx: RuntimeContext) { - const { engine } = ctx; - this.protocol = new ObjectStackRuntimeProtocol(engine); - this.setupHandlers(); - } - - /** - * Legacy RuntimePlugin interface - onStart - */ - async onStart(ctx: RuntimeContext) { - await this.startWorker(); - } - - /** - * Legacy RuntimePlugin interface - onStop - */ - async onStop() { - await this.stopWorker(); - } - /** * Setup MSW handlers */