bun_plugins 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/Plugin.d.ts +28 -0
- package/dist/Plugin.d.ts.map +1 -0
- package/dist/Plugin.js +36 -0
- package/dist/Plugin.js.map +1 -0
- package/dist/PluginManager.d.ts +9 -0
- package/dist/PluginManager.d.ts.map +1 -1
- package/dist/PluginManager.js +147 -43
- package/dist/PluginManager.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/logger/LoggerAdapter.d.ts +77 -0
- package/dist/logger/LoggerAdapter.d.ts.map +1 -0
- package/dist/logger/LoggerAdapter.js +244 -0
- package/dist/logger/LoggerAdapter.js.map +1 -0
- package/dist/logger/LoggerFactory.d.ts +73 -0
- package/dist/logger/LoggerFactory.d.ts.map +1 -0
- package/dist/logger/LoggerFactory.js +99 -0
- package/dist/logger/LoggerFactory.js.map +1 -0
- package/dist/logger/index.d.ts +3 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +3 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/managers/ContextFactory.d.ts +1 -1
- package/dist/managers/ContextFactory.d.ts.map +1 -1
- package/dist/managers/ContextFactory.js +15 -11
- package/dist/managers/ContextFactory.js.map +1 -1
- package/dist/managers/DependencyManager.d.ts.map +1 -1
- package/dist/managers/DependencyManager.js +2 -0
- package/dist/managers/DependencyManager.js.map +1 -1
- package/dist/managers/HooksManager.d.ts +4 -1
- package/dist/managers/HooksManager.d.ts.map +1 -1
- package/dist/managers/HooksManager.js +36 -8
- package/dist/managers/HooksManager.js.map +1 -1
- package/dist/managers/ResourceManager.d.ts.map +1 -1
- package/dist/managers/ResourceManager.js +2 -1
- package/dist/managers/ResourceManager.js.map +1 -1
- package/dist/pluginRegistry.d.ts +13 -0
- package/dist/pluginRegistry.d.ts.map +1 -0
- package/dist/pluginRegistry.js +11 -0
- package/dist/pluginRegistry.js.map +1 -0
- package/dist/plugins/ActionRegistryPlugin.d.ts +23 -0
- package/dist/plugins/ActionRegistryPlugin.d.ts.map +1 -0
- package/dist/plugins/ActionRegistryPlugin.js +56 -0
- package/dist/plugins/ActionRegistryPlugin.js.map +1 -0
- package/dist/plugins/DynamicJSActionsPlugin.d.ts +21 -0
- package/dist/plugins/DynamicJSActionsPlugin.d.ts.map +1 -0
- package/dist/plugins/DynamicJSActionsPlugin.js +57 -0
- package/dist/plugins/DynamicJSActionsPlugin.js.map +1 -0
- package/dist/plugins/DynamicMathActionsPlugin.d.ts +22 -0
- package/dist/plugins/DynamicMathActionsPlugin.d.ts.map +1 -0
- package/dist/plugins/DynamicMathActionsPlugin.js +64 -0
- package/dist/plugins/DynamicMathActionsPlugin.js.map +1 -0
- package/dist/plugins/DynamicTextActionsPlugin.d.ts +22 -0
- package/dist/plugins/DynamicTextActionsPlugin.d.ts.map +1 -0
- package/dist/plugins/DynamicTextActionsPlugin.js +58 -0
- package/dist/plugins/DynamicTextActionsPlugin.js.map +1 -0
- package/dist/plugins/DynamicUtilityActionsPlugin.d.ts +22 -0
- package/dist/plugins/DynamicUtilityActionsPlugin.d.ts.map +1 -0
- package/dist/plugins/DynamicUtilityActionsPlugin.js +75 -0
- package/dist/plugins/DynamicUtilityActionsPlugin.js.map +1 -0
- package/dist/plugins/ExamplePlugin.d.ts +3 -0
- package/dist/plugins/ExamplePlugin.d.ts.map +1 -0
- package/dist/plugins/ExamplePlugin.js +41 -0
- package/dist/plugins/ExamplePlugin.js.map +1 -0
- package/dist/plugins/LifecycleDemoPlugin.d.ts +20 -0
- package/dist/plugins/LifecycleDemoPlugin.d.ts.map +1 -0
- package/dist/plugins/LifecycleDemoPlugin.js +34 -0
- package/dist/plugins/LifecycleDemoPlugin.js.map +1 -0
- package/dist/plugins/MathPlugin.d.ts +16 -0
- package/dist/plugins/MathPlugin.d.ts.map +1 -0
- package/dist/plugins/MathPlugin.js +25 -0
- package/dist/plugins/MathPlugin.js.map +1 -0
- package/dist/plugins/MyJSPlugin.d.ts +7 -0
- package/dist/plugins/MyJSPlugin.d.ts.map +1 -0
- package/dist/plugins/MyJSPlugin.js +12 -0
- package/dist/plugins/MyJSPlugin.js.map +1 -0
- package/dist/plugins/arktype/index.d.ts +8 -0
- package/dist/plugins/arktype/index.d.ts.map +1 -0
- package/dist/plugins/arktype/index.js +25 -0
- package/dist/plugins/arktype/index.js.map +1 -0
- package/dist/src/Plugin.d.ts +28 -0
- package/dist/src/Plugin.d.ts.map +1 -0
- package/dist/src/Plugin.js +36 -0
- package/dist/src/Plugin.js.map +1 -0
- package/dist/src/PluginManager.d.ts +74 -0
- package/dist/src/PluginManager.d.ts.map +1 -0
- package/dist/src/PluginManager.js +689 -0
- package/dist/src/PluginManager.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/logger/LoggerAdapter.d.ts +77 -0
- package/dist/src/logger/LoggerAdapter.d.ts.map +1 -0
- package/dist/src/logger/LoggerAdapter.js +242 -0
- package/dist/src/logger/LoggerAdapter.js.map +1 -0
- package/dist/src/logger/LoggerFactory.d.ts +73 -0
- package/dist/src/logger/LoggerFactory.d.ts.map +1 -0
- package/dist/src/logger/LoggerFactory.js +99 -0
- package/dist/src/logger/LoggerFactory.js.map +1 -0
- package/dist/src/logger/index.d.ts +3 -0
- package/dist/src/logger/index.d.ts.map +1 -0
- package/dist/src/logger/index.js +3 -0
- package/dist/src/logger/index.js.map +1 -0
- package/dist/src/managers/ContextFactory.d.ts +6 -0
- package/dist/src/managers/ContextFactory.d.ts.map +1 -0
- package/dist/src/managers/ContextFactory.js +132 -0
- package/dist/src/managers/ContextFactory.js.map +1 -0
- package/dist/src/managers/DependencyManager.d.ts +10 -0
- package/dist/src/managers/DependencyManager.d.ts.map +1 -0
- package/dist/src/managers/DependencyManager.js +96 -0
- package/dist/src/managers/DependencyManager.js.map +1 -0
- package/dist/src/managers/HooksManager.d.ts +24 -0
- package/dist/src/managers/HooksManager.d.ts.map +1 -0
- package/dist/src/managers/HooksManager.js +145 -0
- package/dist/src/managers/HooksManager.js.map +1 -0
- package/dist/src/managers/ResourceManager.d.ts +16 -0
- package/dist/src/managers/ResourceManager.d.ts.map +1 -0
- package/dist/src/managers/ResourceManager.js +50 -0
- package/dist/src/managers/ResourceManager.js.map +1 -0
- package/dist/src/pluginRegistry.d.ts +13 -0
- package/dist/src/pluginRegistry.d.ts.map +1 -0
- package/dist/src/pluginRegistry.js +11 -0
- package/dist/src/pluginRegistry.js.map +1 -0
- package/dist/src/storage/JsonPluginStorage.d.ts +15 -0
- package/dist/src/storage/JsonPluginStorage.d.ts.map +1 -0
- package/dist/src/storage/JsonPluginStorage.js +75 -0
- package/dist/src/storage/JsonPluginStorage.js.map +1 -0
- package/dist/src/types/arktype_converter.d.ts +19 -0
- package/dist/src/types/arktype_converter.d.ts.map +1 -0
- package/dist/src/types/arktype_converter.js +73 -0
- package/dist/src/types/arktype_converter.js.map +1 -0
- package/dist/src/types/generator.d.ts +8 -0
- package/dist/src/types/generator.d.ts.map +1 -0
- package/dist/src/types/generator.js +9 -0
- package/dist/src/types/generator.js.map +1 -0
- package/dist/src/types/interfaces.d.ts +55 -0
- package/dist/src/types/interfaces.d.ts.map +1 -0
- package/dist/src/types/interfaces.js +5 -0
- package/dist/src/types/interfaces.js.map +1 -0
- package/dist/src/types/plugin-registry.d.ts +21 -0
- package/dist/src/types/plugin-registry.d.ts.map +1 -0
- package/dist/src/types/plugin-registry.js +4 -0
- package/dist/src/types/plugin-registry.js.map +1 -0
- package/dist/src/types/plugin_generator.d.ts +56 -0
- package/dist/src/types/plugin_generator.d.ts.map +1 -0
- package/dist/src/types/plugin_generator.js +659 -0
- package/dist/src/types/plugin_generator.js.map +1 -0
- package/dist/src/types.d.ts +211 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +62 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils/errorParser.d.ts +3 -0
- package/dist/src/utils/errorParser.d.ts.map +1 -0
- package/dist/src/utils/errorParser.js +23 -0
- package/dist/src/utils/errorParser.js.map +1 -0
- package/dist/src/utils/pluginValidator.d.ts +17 -0
- package/dist/src/utils/pluginValidator.d.ts.map +1 -0
- package/dist/src/utils/pluginValidator.js +74 -0
- package/dist/src/utils/pluginValidator.js.map +1 -0
- package/dist/src/utils/security.d.ts +3 -0
- package/dist/src/utils/security.d.ts.map +1 -0
- package/dist/src/utils/security.js +26 -0
- package/dist/src/utils/security.js.map +1 -0
- package/dist/src/worker/WorkerRunner.d.ts +2 -0
- package/dist/src/worker/WorkerRunner.d.ts.map +1 -0
- package/dist/src/worker/WorkerRunner.js +274 -0
- package/dist/src/worker/WorkerRunner.js.map +1 -0
- package/dist/storage/JsonPluginStorage.d.ts +2 -1
- package/dist/storage/JsonPluginStorage.d.ts.map +1 -1
- package/dist/storage/JsonPluginStorage.js +26 -14
- package/dist/storage/JsonPluginStorage.js.map +1 -1
- package/dist/types.d.ts +26 -7
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -1
- package/dist/types.js.map +1 -1
- package/dist/worker/WorkerRunner.js +32 -12
- package/dist/worker/WorkerRunner.js.map +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -163,7 +163,7 @@ Plugins can share APIs with each other safely:
|
|
|
163
163
|
// Plugin A: Exposes an API
|
|
164
164
|
export class ProviderPlugin implements IPlugin {
|
|
165
165
|
name = "db-provider";
|
|
166
|
-
|
|
166
|
+
getApi() {
|
|
167
167
|
return {
|
|
168
168
|
query: (q: string) => `Result for ${q}`,
|
|
169
169
|
};
|
|
@@ -174,7 +174,7 @@ export class ProviderPlugin implements IPlugin {
|
|
|
174
174
|
export class ConsumerPlugin implements IPlugin {
|
|
175
175
|
name = "app-logic";
|
|
176
176
|
async onLoad(context: PluginContext) {
|
|
177
|
-
const db = context.getPlugin("db-provider");
|
|
177
|
+
const db = await context.getPlugin("db-provider");
|
|
178
178
|
const result = db.query("SELECT *");
|
|
179
179
|
}
|
|
180
180
|
}
|
package/dist/Plugin.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IPlugin, PluginContext, PluginBuilder, PluginPermission } from "./types";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
/**
|
|
4
|
+
* Abstract base class for Plugins to extend.
|
|
5
|
+
* Provides default implementations for optional methods.
|
|
6
|
+
*/
|
|
7
|
+
export declare abstract class Plugin implements IPlugin {
|
|
8
|
+
abstract name: string;
|
|
9
|
+
abstract version: string;
|
|
10
|
+
description?: string;
|
|
11
|
+
author?: string;
|
|
12
|
+
dependencies?: Record<string, string>;
|
|
13
|
+
permissions?: PluginPermission[];
|
|
14
|
+
allowedDomains?: string[];
|
|
15
|
+
configSchema?: z.ZodSchema;
|
|
16
|
+
defaultConfig?: Record<string, any>;
|
|
17
|
+
onLoad(context: PluginContext): Promise<void> | void;
|
|
18
|
+
onUnload(): Promise<void> | void;
|
|
19
|
+
onStarted(): Promise<void> | void;
|
|
20
|
+
onReload(context: PluginContext): Promise<void> | void;
|
|
21
|
+
setup(build: PluginBuilder): void | Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Helper function to define a plugin object with type inference.
|
|
25
|
+
* Useful for functional-style plugin definitions.
|
|
26
|
+
*/
|
|
27
|
+
export declare function definePlugin(plugin: IPlugin): IPlugin;
|
|
28
|
+
//# sourceMappingURL=Plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Plugin.d.ts","sourceRoot":"","sources":["../src/Plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACvF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,8BAAsB,MAAO,YAAW,OAAO;IAC3C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAEpC,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIpD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIhC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIjC,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAItD,KAAK,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAGpD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAErD"}
|
package/dist/Plugin.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract base class for Plugins to extend.
|
|
3
|
+
* Provides default implementations for optional methods.
|
|
4
|
+
*/
|
|
5
|
+
export class Plugin {
|
|
6
|
+
description;
|
|
7
|
+
author;
|
|
8
|
+
dependencies;
|
|
9
|
+
permissions;
|
|
10
|
+
allowedDomains;
|
|
11
|
+
configSchema;
|
|
12
|
+
defaultConfig;
|
|
13
|
+
onLoad(context) {
|
|
14
|
+
// Default no-op
|
|
15
|
+
}
|
|
16
|
+
onUnload() {
|
|
17
|
+
// Default no-op
|
|
18
|
+
}
|
|
19
|
+
onStarted() {
|
|
20
|
+
// Default no-op
|
|
21
|
+
}
|
|
22
|
+
onReload(context) {
|
|
23
|
+
// Default no-op defined but not enforced by interface strictly if optional
|
|
24
|
+
}
|
|
25
|
+
setup(build) {
|
|
26
|
+
// Default no-op
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Helper function to define a plugin object with type inference.
|
|
31
|
+
* Useful for functional-style plugin definitions.
|
|
32
|
+
*/
|
|
33
|
+
export function definePlugin(plugin) {
|
|
34
|
+
return plugin;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=Plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Plugin.js","sourceRoot":"","sources":["../src/Plugin.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,OAAgB,MAAM;IAIxB,WAAW,CAAU;IACrB,MAAM,CAAU;IAChB,YAAY,CAA0B;IACtC,WAAW,CAAsB;IACjC,cAAc,CAAY;IAC1B,YAAY,CAAe;IAC3B,aAAa,CAAuB;IAEpC,MAAM,CAAC,OAAsB;QACzB,gBAAgB;IACpB,CAAC;IAED,QAAQ;QACJ,gBAAgB;IACpB,CAAC;IAED,SAAS;QACL,gBAAgB;IACpB,CAAC;IAED,QAAQ,CAAC,OAAsB;QAC3B,2EAA2E;IAC/E,CAAC;IAED,KAAK,CAAC,KAAoB;QACtB,gBAAgB;IACpB,CAAC;CACJ;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAe;IACxC,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
package/dist/PluginManager.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { EventEmitter } from "node:events";
|
|
2
2
|
import { type IPlugin, type AppEvents, type BunWorkerOptions as WorkerOptions, type OnResolveArgs, type OnLoadArgs, type IPluginManager } from "./types";
|
|
3
|
+
import { PluginTypeByName, KnownPluginNames } from "./pluginRegistry";
|
|
3
4
|
import { HooksManager } from "./managers/HooksManager";
|
|
4
5
|
export declare class PluginManager extends EventEmitter implements IPluginManager {
|
|
5
6
|
private plugins;
|
|
6
7
|
private availablePlugins;
|
|
8
|
+
private configs;
|
|
7
9
|
private resources;
|
|
8
10
|
private dependencyManager;
|
|
9
11
|
hooksManager: HooksManager;
|
|
@@ -22,6 +24,8 @@ export declare class PluginManager extends EventEmitter implements IPluginManage
|
|
|
22
24
|
registerIsolated(pluginPath: string, pluginName: string): Promise<void>;
|
|
23
25
|
unregister(pluginName: string): Promise<void>;
|
|
24
26
|
getPlugin(name: string): IPlugin | undefined;
|
|
27
|
+
getPlugin<TName extends string>(name: TName): TName extends KnownPluginNames ? PluginTypeByName<TName> : IPlugin | undefined;
|
|
28
|
+
getPluginConfig(name: string): Record<string, any>;
|
|
25
29
|
listPlugins(): string[];
|
|
26
30
|
emit<K extends keyof AppEvents>(eventName: K, payload: AppEvents[K]): boolean;
|
|
27
31
|
emit(eventName: string | symbol, ...args: any[]): boolean;
|
|
@@ -44,6 +48,9 @@ export declare class PluginManager extends EventEmitter implements IPluginManage
|
|
|
44
48
|
contents?: string;
|
|
45
49
|
loader?: string;
|
|
46
50
|
} | null>;
|
|
51
|
+
use(plugin: IPlugin): Promise<void>;
|
|
52
|
+
plugin(plugin: IPlugin): Promise<void>;
|
|
53
|
+
remove(pluginName: string): Promise<void>;
|
|
47
54
|
toBunPlugin(): Bun.BunPlugin;
|
|
48
55
|
private hotReloadTimer;
|
|
49
56
|
enableHotReload(pluginDir: string): void;
|
|
@@ -57,10 +64,12 @@ export declare class PluginManager extends EventEmitter implements IPluginManage
|
|
|
57
64
|
pluginCount: number;
|
|
58
65
|
};
|
|
59
66
|
hooks: {
|
|
67
|
+
onStart: number;
|
|
60
68
|
onResolve: number;
|
|
61
69
|
onLoad: number;
|
|
62
70
|
};
|
|
63
71
|
};
|
|
64
72
|
getPluginStatus(): Record<string, any>;
|
|
73
|
+
private ensureDependenciesInstalled;
|
|
65
74
|
}
|
|
66
75
|
//# sourceMappingURL=PluginManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PluginManager.d.ts","sourceRoot":"","sources":["../src/PluginManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,EACH,KAAK,OAAO,EAEZ,KAAK,SAAS,EACd,KAAK,gBAAgB,IAAI,aAAa,EACtC,KAAK,aAAa,EAClB,KAAK,UAAU,EACf,KAAK,cAAc,EAKtB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"PluginManager.d.ts","sourceRoot":"","sources":["../src/PluginManager.ts"],"names":[],"mappings":"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"}
|
package/dist/PluginManager.js
CHANGED
|
@@ -12,9 +12,11 @@ import { HooksManager } from "./managers/HooksManager";
|
|
|
12
12
|
import { createPluginContext } from "./managers/ContextFactory";
|
|
13
13
|
import { errorParser } from "./utils/errorParser";
|
|
14
14
|
import { checkNetworkPermission, checkPermission as checkGeneralPermission } from "./utils/security";
|
|
15
|
+
import { logger } from "./logger";
|
|
15
16
|
export class PluginManager extends EventEmitter {
|
|
16
17
|
plugins = new Map();
|
|
17
18
|
availablePlugins = new Map();
|
|
19
|
+
configs = new Map();
|
|
18
20
|
// Modules
|
|
19
21
|
resources;
|
|
20
22
|
dependencyManager;
|
|
@@ -59,7 +61,7 @@ export class PluginManager extends EventEmitter {
|
|
|
59
61
|
throw new Error(`Plugin ${plugin.name} requires host version ${plugin.engines.host}, but found ${this.hostVersion}`);
|
|
60
62
|
}
|
|
61
63
|
}
|
|
62
|
-
|
|
64
|
+
logger.getLogger("PluginManager").info(`Loading plugin: ${plugin.name} v${plugin.version}`);
|
|
63
65
|
// 1. Prepare Storage
|
|
64
66
|
const storage = new JsonPluginStorage(this.storageRoot, plugin.name);
|
|
65
67
|
// 2. Load & Validate Configuration
|
|
@@ -70,7 +72,7 @@ export class PluginManager extends EventEmitter {
|
|
|
70
72
|
}
|
|
71
73
|
catch (e) {
|
|
72
74
|
const error = errorParser(e, `Error in plugin ${plugin.name}`);
|
|
73
|
-
|
|
75
|
+
logger.getLogger("PluginManager").warn(`[SafeMode] Using default config, validation failed. Error: ${error.message}`);
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
78
|
// 3. Initialize Resources
|
|
@@ -80,14 +82,15 @@ export class PluginManager extends EventEmitter {
|
|
|
80
82
|
throw new Error(`Invalid plugin name: ${plugin.name}. Name cannot contain path traversal characters.`);
|
|
81
83
|
}
|
|
82
84
|
// 4. Context Creation
|
|
83
|
-
|
|
85
|
+
this.configs.set(plugin.name, config);
|
|
86
|
+
const context = createPluginContext(this, plugin, this.resources, storage);
|
|
84
87
|
// 5. Setup Hooks with Performance Monitoring (Delegated to HooksManager via Builder)
|
|
85
88
|
if (plugin.setup) {
|
|
86
89
|
try {
|
|
87
|
-
await plugin.setup(this.hooksManager.getBuilder(plugin.name));
|
|
90
|
+
await plugin.setup(this.hooksManager.getBuilder(plugin.name, config));
|
|
88
91
|
}
|
|
89
92
|
catch (e) {
|
|
90
|
-
|
|
93
|
+
logger.getLogger("PluginManager").error(`Error during setup for ${plugin.name}:`, e);
|
|
91
94
|
throw errorParser(e, `Error during setup for ${plugin.name}`);
|
|
92
95
|
}
|
|
93
96
|
}
|
|
@@ -98,19 +101,21 @@ export class PluginManager extends EventEmitter {
|
|
|
98
101
|
await Promise.race([plugin.onLoad(context), timeoutPromise]);
|
|
99
102
|
const duration = performance.now() - start;
|
|
100
103
|
this.plugins.set(plugin.name, plugin);
|
|
101
|
-
|
|
104
|
+
logger.getLogger("PluginManager").info(`Plugin ${plugin.name} loaded successfully in ${duration.toFixed(2)}ms.`);
|
|
102
105
|
// Trigger onStarted after registration if provided
|
|
103
106
|
if (plugin.onStarted) {
|
|
104
107
|
try {
|
|
105
108
|
await plugin.onStarted();
|
|
106
109
|
}
|
|
107
110
|
catch (e) {
|
|
108
|
-
|
|
111
|
+
logger.getLogger("PluginManager").error(`Error in onStarted for ${plugin.name}:`, e);
|
|
109
112
|
}
|
|
110
113
|
}
|
|
114
|
+
// 7. Trigger onStart hooks registered via setup()
|
|
115
|
+
await this.hooksManager.runOnStart();
|
|
111
116
|
}
|
|
112
117
|
catch (error) {
|
|
113
|
-
|
|
118
|
+
logger.getLogger("PluginManager").error(`Failed to load plugin ${plugin.name}:`, error);
|
|
114
119
|
// Cleanup resources directly since plugin is not in this.plugins yet
|
|
115
120
|
this.resources.cleanup(plugin.name, this);
|
|
116
121
|
this.hooksManager.cleanup(plugin.name);
|
|
@@ -120,7 +125,7 @@ export class PluginManager extends EventEmitter {
|
|
|
120
125
|
async registerIsolated(pluginPath, pluginName) {
|
|
121
126
|
return new Promise((resolve, reject) => {
|
|
122
127
|
const workerScript = this.workerRunnerPath;
|
|
123
|
-
|
|
128
|
+
logger.getLogger("PluginManager").info("Worker Path:", workerScript);
|
|
124
129
|
const timeoutId = setTimeout(() => {
|
|
125
130
|
worker.terminate();
|
|
126
131
|
reject(new Error(`Isolated plugin ${pluginName} timed out during loading (${this.pluginLoadTimeout}ms)`));
|
|
@@ -201,16 +206,22 @@ export class PluginManager extends EventEmitter {
|
|
|
201
206
|
else if (type === HookType.ON_LOAD) {
|
|
202
207
|
this.hooksManager.registerOnLoad(filterRegExp, proxyCallback, pluginName, options?.order);
|
|
203
208
|
}
|
|
209
|
+
else if (type === HookType.ON_START) {
|
|
210
|
+
this.hooksManager.registerOnStart(() => proxyCallback({}), pluginName);
|
|
211
|
+
}
|
|
204
212
|
result = true;
|
|
205
213
|
}
|
|
206
214
|
else if (method === RPCMethod.ManagerGetPlugin) {
|
|
207
215
|
const targetName = args[0];
|
|
208
216
|
const p = this.getPlugin(targetName);
|
|
209
|
-
result = p
|
|
217
|
+
result = p && typeof p === 'object' && 'getSharedApi' in p && typeof p.getSharedApi === 'function'
|
|
218
|
+
? p.getSharedApi()
|
|
219
|
+
: undefined;
|
|
210
220
|
}
|
|
211
221
|
else if (method === RPCMethod.Log) {
|
|
212
222
|
const level = args[0];
|
|
213
|
-
|
|
223
|
+
const [msg, ...restArgs] = args.slice(1);
|
|
224
|
+
logger.getLogger(pluginName)[level](msg, ...restArgs);
|
|
214
225
|
result = true;
|
|
215
226
|
}
|
|
216
227
|
else if (method === RPCMethod.PermissionCheck) {
|
|
@@ -235,6 +246,13 @@ export class PluginManager extends EventEmitter {
|
|
|
235
246
|
body: await response.text()
|
|
236
247
|
};
|
|
237
248
|
}
|
|
249
|
+
else if (method === RPCMethod.ConfigGet) {
|
|
250
|
+
result = this.getPluginConfig(pluginName);
|
|
251
|
+
}
|
|
252
|
+
else if (method === RPCMethod.StorageReload) {
|
|
253
|
+
await storage.reload();
|
|
254
|
+
result = true;
|
|
255
|
+
}
|
|
238
256
|
worker.postMessage({ id, result });
|
|
239
257
|
}
|
|
240
258
|
catch (e) {
|
|
@@ -261,7 +279,7 @@ export class PluginManager extends EventEmitter {
|
|
|
261
279
|
else if (msg.type === WorkerMessageType.MANIFEST) {
|
|
262
280
|
const { metadata } = msg;
|
|
263
281
|
pluginMetadata = metadata;
|
|
264
|
-
|
|
282
|
+
logger.getLogger("PluginManager").info(`Metadata received for isolated plugin: ${metadata.name}`);
|
|
265
283
|
}
|
|
266
284
|
else if (msg.type === WorkerMessageType.LOAD_SUCCESS) {
|
|
267
285
|
clearTimeout(timeoutId); // Success, clear global timeout
|
|
@@ -291,7 +309,7 @@ export class PluginManager extends EventEmitter {
|
|
|
291
309
|
},
|
|
292
310
|
};
|
|
293
311
|
this.plugins.set(metadata.name, proxyPlugin);
|
|
294
|
-
|
|
312
|
+
logger.getLogger("PluginManager").info(`Isolated Plugin ${metadata.name} loaded in worker.`);
|
|
295
313
|
resolve();
|
|
296
314
|
}
|
|
297
315
|
else if (msg.type === WorkerMessageType.LOAD_ERROR) {
|
|
@@ -308,7 +326,7 @@ export class PluginManager extends EventEmitter {
|
|
|
308
326
|
worker.addEventListener("message", (event) => rpcHandler(event.data));
|
|
309
327
|
worker.addEventListener("error", (err) => {
|
|
310
328
|
clearTimeout(timeoutId);
|
|
311
|
-
|
|
329
|
+
logger.getLogger("PluginManager").error(`[Isolated:${pluginName}] Worker Error:`, err);
|
|
312
330
|
// Reject all pending hooks on crash
|
|
313
331
|
for (const pending of Array.from(pendingHooks.values())) {
|
|
314
332
|
pending.reject(new Error("Worker terminated unexpectedly"));
|
|
@@ -324,24 +342,34 @@ export class PluginManager extends EventEmitter {
|
|
|
324
342
|
return;
|
|
325
343
|
for (const [name, p] of Array.from(this.plugins.entries())) {
|
|
326
344
|
if (p.dependencies && p.dependencies[pluginName]) {
|
|
327
|
-
|
|
345
|
+
logger.getLogger("PluginManager").warn(`Warning: Plugin ${name} depends on ${pluginName} which is being unloaded.`);
|
|
328
346
|
}
|
|
329
347
|
}
|
|
330
348
|
try {
|
|
331
349
|
await plugin.onUnload();
|
|
332
350
|
}
|
|
333
351
|
catch (error) {
|
|
334
|
-
|
|
352
|
+
logger.getLogger("PluginManager").error(`Error unloading plugin ${pluginName}:`, error);
|
|
335
353
|
}
|
|
336
354
|
finally {
|
|
337
355
|
this.plugins.delete(pluginName);
|
|
338
356
|
this.resources.cleanup(pluginName, this);
|
|
339
357
|
this.hooksManager.cleanup(pluginName);
|
|
340
|
-
|
|
358
|
+
logger.getLogger("PluginManager").info(`Plugin ${pluginName} unloaded.`);
|
|
341
359
|
}
|
|
342
360
|
}
|
|
343
361
|
getPlugin(name) {
|
|
344
|
-
|
|
362
|
+
const plugin = this.plugins.get(name);
|
|
363
|
+
if (!plugin)
|
|
364
|
+
return undefined;
|
|
365
|
+
// Si el plugin tiene getSharedApi, retornar la API compartida
|
|
366
|
+
if (plugin.getSharedApi) {
|
|
367
|
+
return plugin.getSharedApi();
|
|
368
|
+
}
|
|
369
|
+
return plugin;
|
|
370
|
+
}
|
|
371
|
+
getPluginConfig(name) {
|
|
372
|
+
return this.configs.get(name) || {};
|
|
345
373
|
}
|
|
346
374
|
listPlugins() {
|
|
347
375
|
return Array.from(this.plugins.keys());
|
|
@@ -370,15 +398,35 @@ export class PluginManager extends EventEmitter {
|
|
|
370
398
|
}
|
|
371
399
|
}
|
|
372
400
|
catch (e) {
|
|
373
|
-
|
|
401
|
+
logger.getLogger("PluginManager").warn("Failed to load global plugin config", e);
|
|
374
402
|
}
|
|
375
|
-
const
|
|
403
|
+
const entries = await readdir(directoryPath, { withFileTypes: true });
|
|
376
404
|
this.availablePlugins.clear();
|
|
377
|
-
for (const
|
|
378
|
-
|
|
379
|
-
|
|
405
|
+
for (const entry of entries) {
|
|
406
|
+
let fullPath = null;
|
|
407
|
+
if (entry.isDirectory()) {
|
|
408
|
+
const pluginDir = join(directoryPath, entry.name);
|
|
409
|
+
const pkgPath = join(pluginDir, "package.json");
|
|
410
|
+
if (existsSync(pkgPath)) {
|
|
411
|
+
// Auto-install dependencies if node_modules missing
|
|
412
|
+
await this.ensureDependenciesInstalled(pluginDir);
|
|
413
|
+
fullPath = pluginDir;
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
const distPath = join(pluginDir, "dist");
|
|
417
|
+
if (existsSync(distPath)) {
|
|
418
|
+
fullPath = distPath;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
else if ((entry.name.endsWith(".ts") || entry.name.endsWith(".js")) && !entry.name.endsWith(".d.ts")) {
|
|
423
|
+
fullPath = join(directoryPath, entry.name);
|
|
424
|
+
}
|
|
425
|
+
if (fullPath) {
|
|
380
426
|
try {
|
|
381
|
-
|
|
427
|
+
// Use cache-busting for hot reload
|
|
428
|
+
const query = `?update=${Date.now()}`;
|
|
429
|
+
const module = await import(fullPath + query);
|
|
382
430
|
for (const key in module) {
|
|
383
431
|
const ExportedItem = module[key];
|
|
384
432
|
const validation = validatePlugin(ExportedItem);
|
|
@@ -386,13 +434,13 @@ export class PluginManager extends EventEmitter {
|
|
|
386
434
|
this.availablePlugins.set(validation.plugin.name, validation.plugin);
|
|
387
435
|
}
|
|
388
436
|
else {
|
|
389
|
-
const errorMsg =
|
|
390
|
-
|
|
437
|
+
const errorMsg = validation.error;
|
|
438
|
+
logger.getLogger("PluginManager").warn(`Skipping invalid plugin item in ${entry.name}: ${errorMsg}`);
|
|
391
439
|
}
|
|
392
440
|
}
|
|
393
441
|
}
|
|
394
442
|
catch (err) {
|
|
395
|
-
|
|
443
|
+
logger.getLogger("PluginManager").error(`Error importing ${fullPath}:`, err);
|
|
396
444
|
}
|
|
397
445
|
}
|
|
398
446
|
}
|
|
@@ -402,7 +450,7 @@ export class PluginManager extends EventEmitter {
|
|
|
402
450
|
pluginsToLoad.push(plugin);
|
|
403
451
|
}
|
|
404
452
|
else {
|
|
405
|
-
|
|
453
|
+
logger.getLogger("PluginManager").info(`Plugin ${plugin.name} is disabled.`);
|
|
406
454
|
}
|
|
407
455
|
}
|
|
408
456
|
try {
|
|
@@ -413,7 +461,7 @@ export class PluginManager extends EventEmitter {
|
|
|
413
461
|
if (plugin.dependencies) {
|
|
414
462
|
for (const dep of Object.keys(plugin.dependencies)) {
|
|
415
463
|
if (!this.plugins.has(dep)) {
|
|
416
|
-
|
|
464
|
+
logger.getLogger("PluginManager").warn(`Skipping ${plugin.name}: Dependency ${dep} failed to load or is missing.`);
|
|
417
465
|
dependenciesOk = false;
|
|
418
466
|
break;
|
|
419
467
|
}
|
|
@@ -422,13 +470,18 @@ export class PluginManager extends EventEmitter {
|
|
|
422
470
|
if (!dependenciesOk)
|
|
423
471
|
continue;
|
|
424
472
|
try {
|
|
425
|
-
if (
|
|
473
|
+
if (this.plugins.has(plugin.name)) {
|
|
474
|
+
logger.getLogger("PluginManager").info(`Updating plugin: ${plugin.name}`);
|
|
475
|
+
await this.reloadPlugin(plugin.name);
|
|
476
|
+
loadedPlugins.push(plugin);
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
426
479
|
await this.register(plugin);
|
|
427
480
|
loadedPlugins.push(plugin);
|
|
428
481
|
}
|
|
429
482
|
}
|
|
430
483
|
catch (e) {
|
|
431
|
-
|
|
484
|
+
logger.getLogger("PluginManager").error(`Failed to load/update ${plugin.name}:`, e);
|
|
432
485
|
}
|
|
433
486
|
}
|
|
434
487
|
for (const plugin of loadedPlugins) {
|
|
@@ -437,23 +490,23 @@ export class PluginManager extends EventEmitter {
|
|
|
437
490
|
await plugin.onStarted();
|
|
438
491
|
}
|
|
439
492
|
catch (e) {
|
|
440
|
-
|
|
493
|
+
logger.getLogger("PluginManager").error(`Error in onStarted for ${plugin.name}:`, e);
|
|
441
494
|
}
|
|
442
495
|
}
|
|
443
496
|
}
|
|
444
497
|
}
|
|
445
498
|
catch (e) {
|
|
446
|
-
|
|
499
|
+
logger.getLogger("PluginManager").error("Failed to resolve plugin dependencies or load plugins:", e);
|
|
447
500
|
}
|
|
448
501
|
}
|
|
449
502
|
catch (error) {
|
|
450
|
-
|
|
503
|
+
logger.getLogger("PluginManager").error(`Failed to load plugins from ${directoryPath}`, error);
|
|
451
504
|
}
|
|
452
505
|
}
|
|
453
506
|
async disablePlugin(name) {
|
|
454
507
|
await this.unregister(name);
|
|
455
508
|
await this.updatePluginState(name, true);
|
|
456
|
-
|
|
509
|
+
logger.getLogger("PluginManager").info(`Plugin ${name} disabled.`);
|
|
457
510
|
}
|
|
458
511
|
async enablePlugin(name) {
|
|
459
512
|
await this.updatePluginState(name, false);
|
|
@@ -463,7 +516,7 @@ export class PluginManager extends EventEmitter {
|
|
|
463
516
|
if (plugin.dependencies) {
|
|
464
517
|
for (const dep of Object.keys(plugin.dependencies)) {
|
|
465
518
|
if (!this.plugins.has(dep)) {
|
|
466
|
-
|
|
519
|
+
logger.getLogger("PluginManager").warn(`Cannot enable ${name}: Dependency ${dep} is not loaded.`);
|
|
467
520
|
return;
|
|
468
521
|
}
|
|
469
522
|
}
|
|
@@ -471,19 +524,33 @@ export class PluginManager extends EventEmitter {
|
|
|
471
524
|
await this.register(plugin);
|
|
472
525
|
}
|
|
473
526
|
else {
|
|
474
|
-
|
|
527
|
+
logger.getLogger("PluginManager").warn(`Plugin ${name} enabled but not found in available plugins.`);
|
|
475
528
|
}
|
|
476
529
|
}
|
|
477
530
|
}
|
|
478
531
|
async reloadPlugin(name) {
|
|
479
|
-
const
|
|
480
|
-
if (
|
|
481
|
-
|
|
532
|
+
const oldPlugin = this.plugins.get(name);
|
|
533
|
+
if (oldPlugin) {
|
|
534
|
+
logger.getLogger("PluginManager").info(`Reloading plugin ${name}...`);
|
|
482
535
|
await this.unregister(name);
|
|
483
536
|
}
|
|
484
537
|
const definition = this.availablePlugins.get(name);
|
|
485
538
|
if (definition) {
|
|
486
539
|
await this.register(definition);
|
|
540
|
+
const newPlugin = this.plugins.get(name);
|
|
541
|
+
// If the new version has onReload, call it
|
|
542
|
+
if (newPlugin && newPlugin.onReload) {
|
|
543
|
+
// We need a context for onReload as well
|
|
544
|
+
const storage = new JsonPluginStorage(this.storageRoot, name);
|
|
545
|
+
const context = createPluginContext(this, newPlugin, this.resources, storage);
|
|
546
|
+
try {
|
|
547
|
+
await newPlugin.onReload(context);
|
|
548
|
+
}
|
|
549
|
+
catch (e) {
|
|
550
|
+
logger.getLogger("PluginManager").error(`Error in onReload for ${name}:`, e);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
this.emit("plugin:updated", { name: definition.name, version: definition.version });
|
|
487
554
|
}
|
|
488
555
|
else {
|
|
489
556
|
throw new Error(`Plugin ${name} not found in available plugins.`);
|
|
@@ -509,7 +576,7 @@ export class PluginManager extends EventEmitter {
|
|
|
509
576
|
await Bun.write(globalConfigPath, JSON.stringify(config, null, 2));
|
|
510
577
|
}
|
|
511
578
|
catch (e) {
|
|
512
|
-
|
|
579
|
+
logger.getLogger("PluginManager").error("Failed to update plugin state", e);
|
|
513
580
|
}
|
|
514
581
|
}
|
|
515
582
|
async runOnResolve(args) {
|
|
@@ -518,19 +585,23 @@ export class PluginManager extends EventEmitter {
|
|
|
518
585
|
async runOnLoad(args) {
|
|
519
586
|
return this.hooksManager.runOnLoad(args);
|
|
520
587
|
}
|
|
588
|
+
// Bun-like Aliases
|
|
589
|
+
async use(plugin) { return this.register(plugin); }
|
|
590
|
+
async plugin(plugin) { return this.register(plugin); }
|
|
591
|
+
async remove(pluginName) { return this.unregister(pluginName); }
|
|
521
592
|
toBunPlugin() {
|
|
522
593
|
return this.hooksManager.toBunPlugin();
|
|
523
594
|
}
|
|
524
595
|
hotReloadTimer = null;
|
|
525
596
|
enableHotReload(pluginDir) {
|
|
526
|
-
|
|
597
|
+
logger.getLogger("PluginManager").info(`[HotReload] Watching ${pluginDir} for changes...`);
|
|
527
598
|
watch(pluginDir, { recursive: true }, async (event, filename) => {
|
|
528
599
|
if (!filename || (!filename.endsWith(".ts") && !filename.endsWith(".js")))
|
|
529
600
|
return;
|
|
530
601
|
if (this.hotReloadTimer)
|
|
531
602
|
clearTimeout(this.hotReloadTimer);
|
|
532
603
|
this.hotReloadTimer = setTimeout(async () => {
|
|
533
|
-
|
|
604
|
+
logger.getLogger("PluginManager").info(`[HotReload] Change detected in ${filename}. Re-scanning plugins...`);
|
|
534
605
|
await this.loadPluginsFromDirectory(pluginDir);
|
|
535
606
|
}, 300);
|
|
536
607
|
});
|
|
@@ -541,6 +612,7 @@ export class PluginManager extends EventEmitter {
|
|
|
541
612
|
activePlugins: Array.from(this.plugins.keys()),
|
|
542
613
|
resources: this.resources.getUsageSummary(),
|
|
543
614
|
hooks: {
|
|
615
|
+
onStart: this.hooksManager.getHookCount(HookType.ON_START),
|
|
544
616
|
onResolve: this.hooksManager.getHookCount(HookType.ON_RESOLVE),
|
|
545
617
|
onLoad: this.hooksManager.getHookCount(HookType.ON_LOAD)
|
|
546
618
|
}
|
|
@@ -562,5 +634,37 @@ export class PluginManager extends EventEmitter {
|
|
|
562
634
|
}
|
|
563
635
|
return status;
|
|
564
636
|
}
|
|
637
|
+
async ensureDependenciesInstalled(pluginPath) {
|
|
638
|
+
const nodeModulesPath = join(pluginPath, "node_modules");
|
|
639
|
+
if (!existsSync(nodeModulesPath)) {
|
|
640
|
+
// 1. Check if we are in production
|
|
641
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
642
|
+
if (isProduction) {
|
|
643
|
+
logger.getLogger("PluginManager").warn(`[PluginManager] Warning: Plugin at ${pluginPath} is missing node_modules. Auto-install is disabled in production.`);
|
|
644
|
+
return;
|
|
645
|
+
}
|
|
646
|
+
// 2. Check if 'bun' CLI is even available in the system
|
|
647
|
+
const bunPath = Bun.which("bun");
|
|
648
|
+
if (!bunPath) {
|
|
649
|
+
logger.getLogger("PluginManager").warn(`[PluginManager] Warning: node_modules missing in ${pluginPath}, but 'bun' CLI was not found. Cannot auto-install.`);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
logger.getLogger("PluginManager").info(`[PluginManager] Development mode detected. node_modules missing in ${pluginPath}. Installing deps...`);
|
|
653
|
+
try {
|
|
654
|
+
const proc = Bun.spawn([bunPath, "install"], {
|
|
655
|
+
cwd: pluginPath,
|
|
656
|
+
stdout: "inherit",
|
|
657
|
+
stderr: "inherit",
|
|
658
|
+
});
|
|
659
|
+
const exitCode = await proc.exited;
|
|
660
|
+
if (exitCode !== 0) {
|
|
661
|
+
logger.getLogger("PluginManager").error(`[PluginManager] Failed to install dependencies for ${pluginPath}. Exit code: ${exitCode}`);
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
catch (e) {
|
|
665
|
+
logger.getLogger("PluginManager").error(`[PluginManager] Error running bun install for ${pluginPath}:`, e);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
}
|
|
565
669
|
}
|
|
566
670
|
//# sourceMappingURL=PluginManager.js.map
|