|
1 | 1 | import { Plugin, PluginContext } from '@objectstack/core'; |
2 | | -import { SchemaRegistry, ObjectQL } from './index'; |
3 | 2 |
|
4 | 3 | /** |
5 | 4 | * AppManifestPlugin |
6 | 5 | * |
7 | | - * Wraps an ObjectStack app manifest (objectstack.config.ts export) |
8 | | - * as a Plugin so it can be loaded in the MiniKernel architecture. |
| 6 | + * Adapts a static Manifest JSON into a dynamic Kernel Service. |
| 7 | + * This allows the ObjectQL Engine to "discover" this app during its start phase. |
9 | 8 | * |
10 | | - * Handles: |
11 | | - * - Registering the app/plugin in SchemaRegistry |
12 | | - * - Registering all objects defined in the manifest |
13 | | - * - Seeding data if provided |
14 | | - * |
15 | | - * Dependencies: ['com.objectstack.engine.objectql'] |
| 9 | + * Flow: |
| 10 | + * 1. AppPlugin registers `app.<id>` service (init phase) |
| 11 | + * 2. ObjectQL Engine discovers `app.*` services (start phase) |
16 | 12 | */ |
17 | 13 | export class AppManifestPlugin implements Plugin { |
18 | 14 | name: string; |
19 | 15 | version?: string; |
20 | | - dependencies = ['com.objectstack.engine.objectql']; |
| 16 | + |
| 17 | + // Dependencies removed: This plugin produces data. It doesn't need to consume the engine to register itself. |
| 18 | + // Making it dependency-free allows it to initialize BEFORE the engine if needed. |
21 | 19 |
|
22 | 20 | private manifest: any; |
23 | 21 |
|
24 | 22 | constructor(manifest: any) { |
25 | 23 | this.manifest = manifest; |
26 | 24 | // Support both direct manifest (legacy) and Stack Definition (nested manifest) |
27 | 25 | const sys = manifest.manifest || manifest; |
28 | | - this.name = sys.id || sys.name || 'unnamed-app'; |
| 26 | + const appId = sys.id || sys.name || 'unnamed-app'; |
| 27 | + |
| 28 | + this.name = `plugin.app.${appId}`; // Unique plugin name |
29 | 29 | this.version = sys.version; |
30 | 30 | } |
31 | 31 |
|
32 | 32 | async init(ctx: PluginContext) { |
33 | 33 | // Support both direct manifest (legacy) and Stack Definition (nested manifest) |
34 | 34 | const sys = this.manifest.manifest || this.manifest; |
35 | | - ctx.logger.log(`[AppManifestPlugin] Loading App Manifest: ${sys.id || sys.name}`); |
| 35 | + const appId = sys.id || sys.name; |
| 36 | + |
| 37 | + ctx.logger.log(`[AppManifestPlugin] Registering App Service: ${appId}`); |
36 | 38 |
|
37 | 39 | // Register the app manifest as a service |
38 | | - const serviceName = `app.${sys.id || sys.name}`; |
| 40 | + const serviceName = `app.${appId}`; |
39 | 41 | ctx.registerService(serviceName, this.manifest); |
40 | | - ctx.logger.log(`[AppManifestPlugin] Registered App service: ${serviceName}`); |
41 | 42 | } |
42 | 43 |
|
43 | 44 | async start(ctx: PluginContext) { |
44 | | - // Data seeding logic will be handled by the engine when it detects the app |
| 45 | + // No logic needed here. |
| 46 | + // Logic is inverted: The Engine will pull data from this service. |
45 | 47 | } |
46 | 48 | } |
0 commit comments