feat(FN-3156): add database schema init hook runner for plugin settings lif
The merge adds plugin schema initialization lifecycle support (FN-3156), introduces a ResearchTaskActionModal with model fallback notifications (FN-3012, FN-3008), adds async planning draft sync to prevent UI blocking (FN-3229), and implements viewport-conditional mission split layout (FN-3130). Inf Fusion-Task-Id: FN-3156
This commit is contained in:
@@ -30,6 +30,7 @@ describe("PluginRunner", () => {
|
||||
loadAllPlugins: ReturnType<typeof vi.fn>;
|
||||
stopAllPlugins: ReturnType<typeof vi.fn>;
|
||||
invokeHook: ReturnType<typeof vi.fn>;
|
||||
getPluginSchemaInitHooks: ReturnType<typeof vi.fn>;
|
||||
getPluginTools: ReturnType<typeof vi.fn>;
|
||||
getPluginRoutes: ReturnType<typeof vi.fn>;
|
||||
getPluginUiSlots: ReturnType<typeof vi.fn>;
|
||||
@@ -55,6 +56,7 @@ describe("PluginRunner", () => {
|
||||
on: ReturnType<typeof vi.fn>;
|
||||
off: ReturnType<typeof vi.fn>;
|
||||
getTask: ReturnType<typeof vi.fn>;
|
||||
getDatabase: ReturnType<typeof vi.fn>;
|
||||
};
|
||||
let pluginRunner: PluginRunner;
|
||||
|
||||
@@ -87,6 +89,7 @@ describe("PluginRunner", () => {
|
||||
loadAllPlugins: vi.fn().mockResolvedValue({ loaded: 2, errors: 0 }),
|
||||
stopAllPlugins: vi.fn().mockResolvedValue(undefined),
|
||||
invokeHook: vi.fn().mockResolvedValue(undefined),
|
||||
getPluginSchemaInitHooks: vi.fn().mockReturnValue([]),
|
||||
getPluginTools: vi.fn().mockReturnValue([]),
|
||||
getPluginRoutes: vi.fn().mockReturnValue([]),
|
||||
getPluginUiSlots: vi.fn().mockReturnValue([]),
|
||||
@@ -106,10 +109,12 @@ describe("PluginRunner", () => {
|
||||
|
||||
const mockOn = vi.fn();
|
||||
const mockOff = vi.fn();
|
||||
const mockRunPluginSchemaInits = vi.fn().mockResolvedValue(undefined);
|
||||
mockTaskStore = {
|
||||
on: mockOn,
|
||||
off: mockOff,
|
||||
getTask: vi.fn(),
|
||||
getDatabase: vi.fn().mockReturnValue({ runPluginSchemaInits: mockRunPluginSchemaInits }),
|
||||
};
|
||||
|
||||
mockPluginStore = {
|
||||
@@ -142,6 +147,32 @@ describe("PluginRunner", () => {
|
||||
expect(mockPluginLoader.loadAllPlugins).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should execute schema init hooks after plugin load", async () => {
|
||||
const schemaHook = vi.fn();
|
||||
mockPluginLoader.getPluginSchemaInitHooks.mockReturnValue([
|
||||
{ pluginId: "plugin-a", hook: schemaHook },
|
||||
]);
|
||||
|
||||
await pluginRunner.init();
|
||||
|
||||
expect(mockPluginLoader.getPluginSchemaInitHooks).toHaveBeenCalledTimes(1);
|
||||
expect(mockTaskStore.getDatabase).toHaveBeenCalledTimes(1);
|
||||
const db = mockTaskStore.getDatabase.mock.results[0]?.value as {
|
||||
runPluginSchemaInits: ReturnType<typeof vi.fn>;
|
||||
};
|
||||
expect(db.runPluginSchemaInits).toHaveBeenCalledWith([
|
||||
{ pluginId: "plugin-a", hook: schemaHook },
|
||||
]);
|
||||
});
|
||||
|
||||
it("should skip schema init execution when no hooks are registered", async () => {
|
||||
mockPluginLoader.getPluginSchemaInitHooks.mockReturnValue([]);
|
||||
|
||||
await pluginRunner.init();
|
||||
|
||||
expect(mockTaskStore.getDatabase).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should subscribe to plugin store events", async () => {
|
||||
await pluginRunner.init();
|
||||
// Should subscribe to plugin lifecycle events
|
||||
|
||||
@@ -157,6 +157,19 @@ export class PluginRunner {
|
||||
const result = await this.options.pluginLoader.loadAllPlugins();
|
||||
executorLog.log(`PluginRunner loaded ${result.loaded} plugins (${result.errors} errors)`);
|
||||
|
||||
// Execute onSchemaInit hooks from loaded plugins.
|
||||
const schemaInitHooks = this.options.pluginLoader.getPluginSchemaInitHooks();
|
||||
if (schemaInitHooks.length > 0) {
|
||||
executorLog.log(`Executing onSchemaInit hooks from ${schemaInitHooks.length} plugins`);
|
||||
try {
|
||||
const db = this.options.taskStore.getDatabase();
|
||||
await db.runPluginSchemaInits(schemaInitHooks);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
executorLog.log(`onSchemaInit execution failed: ${message}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Subscribe to store events for task lifecycle hooks
|
||||
this.subscribeToStoreEvents();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user