bun_plugins 1.2.5 → 1.2.6

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.
Files changed (177) hide show
  1. package/README.md +3 -127
  2. package/dist/{src/PluginManager.d.ts → PluginManager.d.ts} +9 -20
  3. package/dist/PluginManager.d.ts.map +1 -0
  4. package/dist/{src/PluginManager.js → PluginManager.js} +189 -212
  5. package/dist/PluginManager.js.map +1 -0
  6. package/dist/{src/index.d.ts → index.d.ts} +1 -2
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/{src/index.js → index.js} +0 -2
  9. package/dist/index.js.map +1 -0
  10. package/dist/{src/managers → managers}/ContextFactory.d.ts +1 -1
  11. package/dist/managers/ContextFactory.d.ts.map +1 -0
  12. package/dist/{src/managers → managers}/ContextFactory.js +26 -51
  13. package/dist/managers/ContextFactory.js.map +1 -0
  14. package/dist/managers/DependencyManager.d.ts.map +1 -0
  15. package/dist/{src/managers → managers}/DependencyManager.js +5 -7
  16. package/dist/managers/DependencyManager.js.map +1 -0
  17. package/dist/{src/managers → managers}/HooksManager.d.ts +1 -4
  18. package/dist/managers/HooksManager.d.ts.map +1 -0
  19. package/dist/{src/managers → managers}/HooksManager.js +8 -36
  20. package/dist/managers/HooksManager.js.map +1 -0
  21. package/dist/managers/ResourceManager.d.ts.map +1 -0
  22. package/dist/{src/managers → managers}/ResourceManager.js +3 -3
  23. package/dist/managers/ResourceManager.js.map +1 -0
  24. package/dist/{src/storage → storage}/JsonPluginStorage.d.ts +1 -2
  25. package/dist/storage/JsonPluginStorage.d.ts.map +1 -0
  26. package/dist/storage/JsonPluginStorage.js +63 -0
  27. package/dist/storage/JsonPluginStorage.js.map +1 -0
  28. package/dist/{src/types.d.ts → types.d.ts} +19 -60
  29. package/dist/types.d.ts.map +1 -0
  30. package/dist/{src/types.js → types.js} +0 -6
  31. package/dist/types.js.map +1 -0
  32. package/dist/utils/errorParser.d.ts.map +1 -0
  33. package/dist/{src/utils → utils}/errorParser.js +5 -2
  34. package/dist/utils/errorParser.js.map +1 -0
  35. package/dist/utils/pluginValidator.d.ts +93 -0
  36. package/dist/utils/pluginValidator.d.ts.map +1 -0
  37. package/dist/{src/utils → utils}/pluginValidator.js +14 -11
  38. package/dist/utils/pluginValidator.js.map +1 -0
  39. package/dist/utils/security.d.ts.map +1 -0
  40. package/dist/utils/security.js.map +1 -0
  41. package/dist/worker/WorkerRunner.d.ts.map +1 -0
  42. package/dist/{src/worker → worker}/WorkerRunner.js +13 -38
  43. package/dist/worker/WorkerRunner.js.map +1 -0
  44. package/package.json +6 -9
  45. package/LICENSE +0 -9
  46. package/dist/examples/action-registry-declarative.d.ts +0 -14
  47. package/dist/examples/action-registry-declarative.d.ts.map +0 -1
  48. package/dist/examples/action-registry-declarative.js +0 -130
  49. package/dist/examples/action-registry-declarative.js.map +0 -1
  50. package/dist/examples/action-registry-example.d.ts +0 -31
  51. package/dist/examples/action-registry-example.d.ts.map +0 -1
  52. package/dist/examples/action-registry-example.js +0 -84
  53. package/dist/examples/action-registry-example.js.map +0 -1
  54. package/dist/examples/index-declarative.d.ts +0 -32
  55. package/dist/examples/index-declarative.d.ts.map +0 -1
  56. package/dist/examples/index-declarative.js +0 -206
  57. package/dist/examples/index-declarative.js.map +0 -1
  58. package/dist/examples/logger-declarative.d.ts +0 -109
  59. package/dist/examples/logger-declarative.d.ts.map +0 -1
  60. package/dist/examples/logger-declarative.js +0 -330
  61. package/dist/examples/logger-declarative.js.map +0 -1
  62. package/dist/examples/logger-simple.d.ts +0 -8
  63. package/dist/examples/logger-simple.d.ts.map +0 -1
  64. package/dist/examples/logger-simple.js +0 -165
  65. package/dist/examples/logger-simple.js.map +0 -1
  66. package/dist/examples/server-declarative.d.ts +0 -46
  67. package/dist/examples/server-declarative.d.ts.map +0 -1
  68. package/dist/examples/server-declarative.js +0 -205
  69. package/dist/examples/server-declarative.js.map +0 -1
  70. package/dist/examples/shared/action-registry.d.ts +0 -45
  71. package/dist/examples/shared/action-registry.d.ts.map +0 -1
  72. package/dist/examples/shared/action-registry.js +0 -65
  73. package/dist/examples/shared/action-registry.js.map +0 -1
  74. package/dist/examples/shared/plugin-builder.d.ts +0 -41
  75. package/dist/examples/shared/plugin-builder.d.ts.map +0 -1
  76. package/dist/examples/shared/plugin-builder.js +0 -85
  77. package/dist/examples/shared/plugin-builder.js.map +0 -1
  78. package/dist/examples/storage-declarative.d.ts +0 -13
  79. package/dist/examples/storage-declarative.d.ts.map +0 -1
  80. package/dist/examples/storage-declarative.js +0 -203
  81. package/dist/examples/storage-declarative.js.map +0 -1
  82. package/dist/plugins/ActionRegistryPlugin.d.ts +0 -14
  83. package/dist/plugins/ActionRegistryPlugin.d.ts.map +0 -1
  84. package/dist/plugins/ActionRegistryPlugin.js +0 -52
  85. package/dist/plugins/ActionRegistryPlugin.js.map +0 -1
  86. package/dist/plugins/DynamicJSActionsPlugin.d.ts +0 -21
  87. package/dist/plugins/DynamicJSActionsPlugin.d.ts.map +0 -1
  88. package/dist/plugins/DynamicJSActionsPlugin.js +0 -57
  89. package/dist/plugins/DynamicJSActionsPlugin.js.map +0 -1
  90. package/dist/plugins/DynamicMathActionsPlugin.d.ts +0 -22
  91. package/dist/plugins/DynamicMathActionsPlugin.d.ts.map +0 -1
  92. package/dist/plugins/DynamicMathActionsPlugin.js +0 -64
  93. package/dist/plugins/DynamicMathActionsPlugin.js.map +0 -1
  94. package/dist/plugins/DynamicTextActionsPlugin.d.ts +0 -22
  95. package/dist/plugins/DynamicTextActionsPlugin.d.ts.map +0 -1
  96. package/dist/plugins/DynamicTextActionsPlugin.js +0 -58
  97. package/dist/plugins/DynamicTextActionsPlugin.js.map +0 -1
  98. package/dist/plugins/DynamicUtilityActionsPlugin.d.ts +0 -22
  99. package/dist/plugins/DynamicUtilityActionsPlugin.d.ts.map +0 -1
  100. package/dist/plugins/DynamicUtilityActionsPlugin.js +0 -75
  101. package/dist/plugins/DynamicUtilityActionsPlugin.js.map +0 -1
  102. package/dist/plugins/ExamplePlugin.d.ts +0 -3
  103. package/dist/plugins/ExamplePlugin.d.ts.map +0 -1
  104. package/dist/plugins/ExamplePlugin.js +0 -24
  105. package/dist/plugins/ExamplePlugin.js.map +0 -1
  106. package/dist/plugins/LifecycleDemoPlugin.d.ts +0 -20
  107. package/dist/plugins/LifecycleDemoPlugin.d.ts.map +0 -1
  108. package/dist/plugins/LifecycleDemoPlugin.js +0 -34
  109. package/dist/plugins/LifecycleDemoPlugin.js.map +0 -1
  110. package/dist/plugins/MathPlugin.d.ts +0 -16
  111. package/dist/plugins/MathPlugin.d.ts.map +0 -1
  112. package/dist/plugins/MathPlugin.js +0 -30
  113. package/dist/plugins/MathPlugin.js.map +0 -1
  114. package/dist/plugins/MyJSPlugin.d.ts +0 -7
  115. package/dist/plugins/MyJSPlugin.d.ts.map +0 -1
  116. package/dist/plugins/MyJSPlugin.js +0 -12
  117. package/dist/plugins/MyJSPlugin.js.map +0 -1
  118. package/dist/plugins/TypedExamplePlugin.d.ts +0 -10
  119. package/dist/plugins/TypedExamplePlugin.d.ts.map +0 -1
  120. package/dist/plugins/TypedExamplePlugin.js +0 -61
  121. package/dist/plugins/TypedExamplePlugin.js.map +0 -1
  122. package/dist/plugins/arktype/index.d.ts +0 -8
  123. package/dist/plugins/arktype/index.d.ts.map +0 -1
  124. package/dist/plugins/arktype/index.js +0 -25
  125. package/dist/plugins/arktype/index.js.map +0 -1
  126. package/dist/src/Plugin.d.ts +0 -28
  127. package/dist/src/Plugin.d.ts.map +0 -1
  128. package/dist/src/Plugin.js +0 -36
  129. package/dist/src/Plugin.js.map +0 -1
  130. package/dist/src/PluginManager.d.ts.map +0 -1
  131. package/dist/src/PluginManager.js.map +0 -1
  132. package/dist/src/index.d.ts.map +0 -1
  133. package/dist/src/index.js.map +0 -1
  134. package/dist/src/logger/LoggerAdapter.d.ts +0 -77
  135. package/dist/src/logger/LoggerAdapter.d.ts.map +0 -1
  136. package/dist/src/logger/LoggerAdapter.js +0 -242
  137. package/dist/src/logger/LoggerAdapter.js.map +0 -1
  138. package/dist/src/logger/LoggerFactory.d.ts +0 -73
  139. package/dist/src/logger/LoggerFactory.d.ts.map +0 -1
  140. package/dist/src/logger/LoggerFactory.js +0 -99
  141. package/dist/src/logger/LoggerFactory.js.map +0 -1
  142. package/dist/src/logger/index.d.ts +0 -3
  143. package/dist/src/logger/index.d.ts.map +0 -1
  144. package/dist/src/logger/index.js +0 -3
  145. package/dist/src/logger/index.js.map +0 -1
  146. package/dist/src/managers/ContextFactory.d.ts.map +0 -1
  147. package/dist/src/managers/ContextFactory.js.map +0 -1
  148. package/dist/src/managers/DependencyManager.d.ts.map +0 -1
  149. package/dist/src/managers/DependencyManager.js.map +0 -1
  150. package/dist/src/managers/HooksManager.d.ts.map +0 -1
  151. package/dist/src/managers/HooksManager.js.map +0 -1
  152. package/dist/src/managers/ResourceManager.d.ts.map +0 -1
  153. package/dist/src/managers/ResourceManager.js.map +0 -1
  154. package/dist/src/storage/JsonPluginStorage.d.ts.map +0 -1
  155. package/dist/src/storage/JsonPluginStorage.js +0 -75
  156. package/dist/src/storage/JsonPluginStorage.js.map +0 -1
  157. package/dist/src/types/plugin-registry-base.d.ts +0 -80
  158. package/dist/src/types/plugin-registry-base.d.ts.map +0 -1
  159. package/dist/src/types/plugin-registry-base.js +0 -6
  160. package/dist/src/types/plugin-registry-base.js.map +0 -1
  161. package/dist/src/types.d.ts.map +0 -1
  162. package/dist/src/types.js.map +0 -1
  163. package/dist/src/utils/errorParser.d.ts.map +0 -1
  164. package/dist/src/utils/errorParser.js.map +0 -1
  165. package/dist/src/utils/pluginValidator.d.ts +0 -17
  166. package/dist/src/utils/pluginValidator.d.ts.map +0 -1
  167. package/dist/src/utils/pluginValidator.js.map +0 -1
  168. package/dist/src/utils/security.d.ts.map +0 -1
  169. package/dist/src/utils/security.js.map +0 -1
  170. package/dist/src/worker/WorkerRunner.d.ts.map +0 -1
  171. package/dist/src/worker/WorkerRunner.js.map +0 -1
  172. /package/dist/{src/managers → managers}/DependencyManager.d.ts +0 -0
  173. /package/dist/{src/managers → managers}/ResourceManager.d.ts +0 -0
  174. /package/dist/{src/utils → utils}/errorParser.d.ts +0 -0
  175. /package/dist/{src/utils → utils}/security.d.ts +0 -0
  176. /package/dist/{src/utils → utils}/security.js +0 -0
  177. /package/dist/{src/worker → worker}/WorkerRunner.d.ts +0 -0
@@ -1,23 +1,21 @@
1
1
  import { EventEmitter } from "node:events";
2
2
  import { readdir, mkdir } from "node:fs/promises";
3
- import { join } from "node:path";
3
+ import { join, dirname } from "node:path";
4
4
  import { watch, existsSync } from "node:fs";
5
5
  import { WorkerMessageType, PluginPermission, RPCMethod, HookType } from "./types";
6
6
  import { validatePlugin } from "./utils/pluginValidator";
7
7
  import { JsonPluginStorage } from "./storage/JsonPluginStorage";
8
- import * as semver from "semver";
8
+ import semver from "semver";
9
9
  import { ResourceManager } from "./managers/ResourceManager";
10
10
  import { DependencyManager } from "./managers/DependencyManager";
11
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";
16
15
  export class PluginManager extends EventEmitter {
17
16
  plugins = new Map();
18
17
  availablePlugins = new Map();
19
- configs = new Map();
20
- pluginApis = new Map();
18
+ pluginFiles = new Map(); // filePath -> pluginName
21
19
  // Modules
22
20
  resources;
23
21
  dependencyManager;
@@ -27,6 +25,8 @@ export class PluginManager extends EventEmitter {
27
25
  pluginLoadTimeout;
28
26
  workerFactory;
29
27
  workerRunnerPath;
28
+ hotReloadWatcher = null;
29
+ hotReloadTimer = null;
30
30
  constructor(storageRoot = join(process.cwd(), "storage"), options) {
31
31
  super();
32
32
  this.storageRoot = storageRoot;
@@ -62,7 +62,7 @@ export class PluginManager extends EventEmitter {
62
62
  throw new Error(`Plugin ${plugin.name} requires host version ${plugin.engines.host}, but found ${this.hostVersion}`);
63
63
  }
64
64
  }
65
- logger.getLogger("PluginManager").info(`Loading plugin: ${plugin.name} v${plugin.version}`);
65
+ console.log(`Loading plugin: ${plugin.name} v${plugin.version}`);
66
66
  // 1. Prepare Storage
67
67
  const storage = new JsonPluginStorage(this.storageRoot, plugin.name);
68
68
  // 2. Load & Validate Configuration
@@ -73,7 +73,8 @@ export class PluginManager extends EventEmitter {
73
73
  }
74
74
  catch (e) {
75
75
  const error = errorParser(e, `Error in plugin ${plugin.name}`);
76
- logger.getLogger("PluginManager").warn(`[SafeMode] Using default config, validation failed. Error: ${error.message}`);
76
+ console.warn(`[SafeMode] Using default config, validation failed. Error: ${error.message}`);
77
+ config = {}; // Reset to empty config on validation failure to prevent downstream errors
77
78
  }
78
79
  }
79
80
  // 3. Initialize Resources
@@ -83,57 +84,37 @@ export class PluginManager extends EventEmitter {
83
84
  throw new Error(`Invalid plugin name: ${plugin.name}. Name cannot contain path traversal characters.`);
84
85
  }
85
86
  // 4. Context Creation
86
- this.configs.set(plugin.name, config);
87
- const context = createPluginContext(this, plugin, this.resources, storage);
87
+ const context = createPluginContext(this, plugin, this.resources, storage, config);
88
88
  // 5. Setup Hooks with Performance Monitoring (Delegated to HooksManager via Builder)
89
89
  if (plugin.setup) {
90
90
  try {
91
- await plugin.setup(this.hooksManager.getBuilder(plugin.name, config));
91
+ await plugin.setup(this.hooksManager.getBuilder(plugin.name));
92
92
  }
93
93
  catch (e) {
94
- logger.getLogger("PluginManager").error(`Error during setup for ${plugin.name}:`, e);
94
+ console.error(`Error during setup for ${plugin.name}:`, e);
95
95
  throw errorParser(e, `Error during setup for ${plugin.name}`);
96
96
  }
97
97
  }
98
98
  // 6. Lifecycle onLoad
99
99
  try {
100
- let completed = false;
101
- let timeoutError = null;
102
- const timeoutId = setTimeout(() => {
103
- if (!completed) {
104
- completed = true;
105
- timeoutError = new Error(`Plugin ${plugin.name} timed out (${this.pluginLoadTimeout}ms)`);
106
- }
107
- }, this.pluginLoadTimeout);
100
+ const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Plugin ${plugin.name} timed out (${this.pluginLoadTimeout}ms)`)), this.pluginLoadTimeout));
108
101
  const start = performance.now();
109
- try {
110
- await plugin.onLoad(context);
111
- }
112
- finally {
113
- completed = true;
114
- clearTimeout(timeoutId);
115
- }
116
- // Check if timeout triggered
117
- if (timeoutError) {
118
- throw timeoutError;
119
- }
102
+ await Promise.race([plugin.onLoad(context), timeoutPromise]);
120
103
  const duration = performance.now() - start;
121
104
  this.plugins.set(plugin.name, plugin);
122
- logger.getLogger("PluginManager").info(`Plugin ${plugin.name} loaded successfully in ${duration.toFixed(2)}ms.`);
105
+ console.log(`Plugin ${plugin.name} loaded successfully in ${duration.toFixed(2)}ms.`);
123
106
  // Trigger onStarted after registration if provided
124
107
  if (plugin.onStarted) {
125
108
  try {
126
109
  await plugin.onStarted();
127
110
  }
128
111
  catch (e) {
129
- logger.getLogger("PluginManager").error(`Error in onStarted for ${plugin.name}:`, e);
112
+ console.error(`Error in onStarted for ${plugin.name}:`, e);
130
113
  }
131
114
  }
132
- // 7. Trigger onStart hooks registered via setup()
133
- await this.hooksManager.runOnStart();
134
115
  }
135
116
  catch (error) {
136
- logger.getLogger("PluginManager").error(`Failed to load plugin ${plugin.name}:`, error);
117
+ console.error(`Failed to load plugin ${plugin.name}:`, error);
137
118
  // Cleanup resources directly since plugin is not in this.plugins yet
138
119
  this.resources.cleanup(plugin.name, this);
139
120
  this.hooksManager.cleanup(plugin.name);
@@ -143,7 +124,7 @@ export class PluginManager extends EventEmitter {
143
124
  async registerIsolated(pluginPath, pluginName) {
144
125
  return new Promise((resolve, reject) => {
145
126
  const workerScript = this.workerRunnerPath;
146
- logger.getLogger("PluginManager").info("Worker Path:", workerScript);
127
+ console.log("Worker Path:", workerScript);
147
128
  const timeoutId = setTimeout(() => {
148
129
  worker.terminate();
149
130
  reject(new Error(`Isolated plugin ${pluginName} timed out during loading (${this.pluginLoadTimeout}ms)`));
@@ -224,28 +205,16 @@ export class PluginManager extends EventEmitter {
224
205
  else if (type === HookType.ON_LOAD) {
225
206
  this.hooksManager.registerOnLoad(filterRegExp, proxyCallback, pluginName, options?.order);
226
207
  }
227
- else if (type === HookType.ON_START) {
228
- this.hooksManager.registerOnStart(() => proxyCallback({}), pluginName);
229
- }
230
208
  result = true;
231
209
  }
232
210
  else if (method === RPCMethod.ManagerGetPlugin) {
233
211
  const targetName = args[0];
234
- // Get the registered API
235
- const api = this.getPluginApi(targetName);
236
- if (api) {
237
- result = api;
238
- }
239
- else {
240
- // Fallback to the plugin itself
241
- const p = this.getPlugin(targetName);
242
- result = api !== undefined ? api : p || undefined;
243
- }
212
+ const p = this.getPlugin(targetName);
213
+ result = p?.getSharedApi ? p.getSharedApi() : undefined;
244
214
  }
245
215
  else if (method === RPCMethod.Log) {
246
216
  const level = args[0];
247
- const [msg, ...restArgs] = args.slice(1);
248
- logger.getLogger(pluginName)[level](msg, ...restArgs);
217
+ console[level](`[${pluginName}]`, ...args.slice(1));
249
218
  result = true;
250
219
  }
251
220
  else if (method === RPCMethod.PermissionCheck) {
@@ -261,27 +230,13 @@ export class PluginManager extends EventEmitter {
261
230
  const urlStr = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
262
231
  checkPermission(PluginPermission.Network, urlStr);
263
232
  const response = await fetch(input, init);
264
- const responseHeaders = {};
265
- response.headers.forEach((v, k) => { responseHeaders[k] = v; });
266
233
  result = {
267
234
  status: response.status,
268
235
  statusText: response.statusText,
269
- headers: responseHeaders,
236
+ headers: Object.fromEntries(response.headers.entries()),
270
237
  body: await response.text()
271
238
  };
272
239
  }
273
- else if (method === RPCMethod.ConfigGet) {
274
- result = this.getPluginConfig(pluginName);
275
- }
276
- else if (method === RPCMethod.StorageReload) {
277
- await storage.reload();
278
- result = true;
279
- }
280
- else if (method === RPCMethod.ManagerRegisterApi) {
281
- const [api] = args;
282
- this.registerApi(pluginName, api);
283
- result = true;
284
- }
285
240
  worker.postMessage({ id, result });
286
241
  }
287
242
  catch (e) {
@@ -308,7 +263,7 @@ export class PluginManager extends EventEmitter {
308
263
  else if (msg.type === WorkerMessageType.MANIFEST) {
309
264
  const { metadata } = msg;
310
265
  pluginMetadata = metadata;
311
- logger.getLogger("PluginManager").info(`Metadata received for isolated plugin: ${metadata.name}`);
266
+ console.log(`Metadata received for isolated plugin: ${metadata.name}`);
312
267
  }
313
268
  else if (msg.type === WorkerMessageType.LOAD_SUCCESS) {
314
269
  clearTimeout(timeoutId); // Success, clear global timeout
@@ -331,24 +286,20 @@ export class PluginManager extends EventEmitter {
331
286
  await new Promise(r => setTimeout(r, 200));
332
287
  worker.terminate();
333
288
  // Clear pending hooks on unload
334
- for (const pending of Array.from(pendingHooks.values())) {
289
+ for (const pending of pendingHooks.values()) {
335
290
  pending.reject(new Error("Plugin unloaded"));
336
291
  }
337
292
  pendingHooks.clear();
338
293
  },
339
294
  };
340
295
  this.plugins.set(metadata.name, proxyPlugin);
341
- // Register API if provided in metadata
342
- if (metadata.api) {
343
- this.registerApi(metadata.name, metadata.api);
344
- }
345
- logger.getLogger("PluginManager").info(`Isolated Plugin ${metadata.name} loaded in worker.`);
296
+ console.log(`Isolated Plugin ${metadata.name} loaded in worker.`);
346
297
  resolve();
347
298
  }
348
299
  else if (msg.type === WorkerMessageType.LOAD_ERROR) {
349
300
  clearTimeout(timeoutId);
350
301
  // Cleanup pending hooks on load error
351
- for (const pending of Array.from(pendingHooks.values())) {
302
+ for (const pending of pendingHooks.values()) {
352
303
  pending.reject(new Error(`Load error: ${msg.error}`));
353
304
  }
354
305
  pendingHooks.clear();
@@ -359,9 +310,9 @@ export class PluginManager extends EventEmitter {
359
310
  worker.addEventListener("message", (event) => rpcHandler(event.data));
360
311
  worker.addEventListener("error", (err) => {
361
312
  clearTimeout(timeoutId);
362
- logger.getLogger("PluginManager").error(`[Isolated:${pluginName}] Worker Error:`, err);
313
+ console.error(`[Isolated:${pluginName}] Worker Error:`, err);
363
314
  // Reject all pending hooks on crash
364
- for (const pending of Array.from(pendingHooks.values())) {
315
+ for (const pending of pendingHooks.values()) {
365
316
  pending.reject(new Error("Worker terminated unexpectedly"));
366
317
  }
367
318
  pendingHooks.clear();
@@ -373,62 +324,36 @@ export class PluginManager extends EventEmitter {
373
324
  const plugin = this.plugins.get(pluginName);
374
325
  if (!plugin)
375
326
  return;
376
- for (const [name, p] of Array.from(this.plugins.entries())) {
327
+ for (const [name, p] of this.plugins.entries()) {
377
328
  if (p.dependencies && p.dependencies[pluginName]) {
378
- logger.getLogger("PluginManager").warn(`Warning: Plugin ${name} depends on ${pluginName} which is being unloaded.`);
329
+ console.warn(`Warning: Plugin ${name} depends on ${pluginName} which is being unloaded.`);
379
330
  }
380
331
  }
381
332
  try {
382
333
  await plugin.onUnload();
383
334
  }
384
335
  catch (error) {
385
- logger.getLogger("PluginManager").error(`Error unloading plugin ${pluginName}:`, error);
336
+ console.error(`Error unloading plugin ${pluginName}:`, error);
386
337
  }
387
338
  finally {
388
339
  this.plugins.delete(pluginName);
389
340
  this.resources.cleanup(pluginName, this);
390
341
  this.hooksManager.cleanup(pluginName);
391
- this.unregisterApi(pluginName);
392
- logger.getLogger("PluginManager").info(`Plugin ${pluginName} unloaded.`);
342
+ console.log(`Plugin ${pluginName} unloaded.`);
393
343
  }
394
344
  }
395
345
  getPlugin(name) {
396
346
  return this.plugins.get(name);
397
347
  }
398
- getApi(name) {
399
- // Get the registered API
400
- return this.getPluginApi(name);
401
- }
402
- getPluginConfig(name) {
403
- return this.configs.get(name) || {};
404
- }
405
348
  listPlugins() {
406
349
  return Array.from(this.plugins.keys());
407
350
  }
408
- // Método para registrar manualmente la API de un plugin
409
- registerApi(pluginName, api) {
410
- this.pluginApis.set(pluginName, api);
411
- }
412
- // Método para obtener la API de un plugin
413
- getPluginApi(pluginName) {
414
- return this.pluginApis.get(pluginName);
415
- }
416
- // Método para limpiar la API de un plugin al desregistrarlo
417
- unregisterApi(pluginName) {
418
- this.pluginApis.delete(pluginName);
419
- }
420
351
  emit(eventName, ...args) {
421
352
  return super.emit(eventName, ...args);
422
353
  }
423
354
  on(eventName, listener) {
424
355
  return super.on(eventName, listener);
425
356
  }
426
- once(eventName, listener) {
427
- return super.once(eventName, listener);
428
- }
429
- off(eventName, listener) {
430
- return super.off(eventName, listener);
431
- }
432
357
  async loadPluginsFromDirectory(directoryPath = join(process.cwd(), "plugins")) {
433
358
  try {
434
359
  const globalConfigPath = join(this.storageRoot, "plugins.json");
@@ -441,35 +366,15 @@ export class PluginManager extends EventEmitter {
441
366
  }
442
367
  }
443
368
  catch (e) {
444
- logger.getLogger("PluginManager").warn("Failed to load global plugin config", e);
369
+ console.warn("Failed to load global plugin config", e);
445
370
  }
446
- const entries = await readdir(directoryPath, { withFileTypes: true });
371
+ const files = await readdir(directoryPath);
447
372
  this.availablePlugins.clear();
448
- for (const entry of entries) {
449
- let fullPath = null;
450
- if (entry.isDirectory()) {
451
- const pluginDir = join(directoryPath, entry.name);
452
- const pkgPath = join(pluginDir, "package.json");
453
- if (existsSync(pkgPath)) {
454
- // Auto-install dependencies if node_modules missing
455
- await this.ensureDependenciesInstalled(pluginDir);
456
- fullPath = pluginDir;
457
- }
458
- else {
459
- const distPath = join(pluginDir, "dist");
460
- if (existsSync(distPath)) {
461
- fullPath = distPath;
462
- }
463
- }
464
- }
465
- else if ((entry.name.endsWith(".ts") || entry.name.endsWith(".js")) && !entry.name.endsWith(".d.ts")) {
466
- fullPath = join(directoryPath, entry.name);
467
- }
468
- if (fullPath) {
373
+ for (const file of files) {
374
+ if ((file.endsWith(".ts") || file.endsWith(".js")) && !file.endsWith(".d.ts")) {
375
+ const fullPath = join(directoryPath, file);
469
376
  try {
470
- // Use cache-busting for hot reload
471
- const query = `?update=${Date.now()}`;
472
- const module = await import(fullPath + query);
377
+ const module = await import(fullPath);
473
378
  for (const key in module) {
474
379
  const ExportedItem = module[key];
475
380
  const validation = validatePlugin(ExportedItem);
@@ -477,23 +382,22 @@ export class PluginManager extends EventEmitter {
477
382
  this.availablePlugins.set(validation.plugin.name, validation.plugin);
478
383
  }
479
384
  else {
480
- const errorMsg = validation.error;
481
- logger.getLogger("PluginManager").warn(`Skipping invalid plugin item in ${entry.name}: ${errorMsg}`);
385
+ console.warn(`Skipping invalid plugin in ${file}: ${validation.error}`);
482
386
  }
483
387
  }
484
388
  }
485
389
  catch (err) {
486
- logger.getLogger("PluginManager").error(`Error importing ${fullPath}:`, err);
390
+ console.error(`Error importing ${fullPath}:`, err);
487
391
  }
488
392
  }
489
393
  }
490
394
  const pluginsToLoad = [];
491
- for (const plugin of Array.from(this.availablePlugins.values())) {
395
+ for (const plugin of this.availablePlugins.values()) {
492
396
  if (!disabledPlugins.includes(plugin.name)) {
493
397
  pluginsToLoad.push(plugin);
494
398
  }
495
399
  else {
496
- logger.getLogger("PluginManager").info(`Plugin ${plugin.name} is disabled.`);
400
+ console.log(`Plugin ${plugin.name} is disabled.`);
497
401
  }
498
402
  }
499
403
  try {
@@ -504,7 +408,7 @@ export class PluginManager extends EventEmitter {
504
408
  if (plugin.dependencies) {
505
409
  for (const dep of Object.keys(plugin.dependencies)) {
506
410
  if (!this.plugins.has(dep)) {
507
- logger.getLogger("PluginManager").warn(`Skipping ${plugin.name}: Dependency ${dep} failed to load or is missing.`);
411
+ console.warn(`Skipping ${plugin.name}: Dependency ${dep} failed to load or is missing.`);
508
412
  dependenciesOk = false;
509
413
  break;
510
414
  }
@@ -513,18 +417,13 @@ export class PluginManager extends EventEmitter {
513
417
  if (!dependenciesOk)
514
418
  continue;
515
419
  try {
516
- if (this.plugins.has(plugin.name)) {
517
- logger.getLogger("PluginManager").info(`Updating plugin: ${plugin.name}`);
518
- await this.reloadPlugin(plugin.name);
519
- loadedPlugins.push(plugin);
520
- }
521
- else {
420
+ if (!this.plugins.has(plugin.name)) {
522
421
  await this.register(plugin);
523
422
  loadedPlugins.push(plugin);
524
423
  }
525
424
  }
526
425
  catch (e) {
527
- logger.getLogger("PluginManager").error(`Failed to load/update ${plugin.name}:`, e);
426
+ console.error(`Failed to load ${plugin.name}:`, e);
528
427
  }
529
428
  }
530
429
  for (const plugin of loadedPlugins) {
@@ -533,23 +432,23 @@ export class PluginManager extends EventEmitter {
533
432
  await plugin.onStarted();
534
433
  }
535
434
  catch (e) {
536
- logger.getLogger("PluginManager").error(`Error in onStarted for ${plugin.name}:`, e);
435
+ console.error(`Error in onStarted for ${plugin.name}:`, e);
537
436
  }
538
437
  }
539
438
  }
540
439
  }
541
440
  catch (e) {
542
- logger.getLogger("PluginManager").error("Failed to resolve plugin dependencies or load plugins:", e);
441
+ console.error("Failed to resolve plugin dependencies or load plugins:", e);
543
442
  }
544
443
  }
545
444
  catch (error) {
546
- logger.getLogger("PluginManager").error(`Failed to load plugins from ${directoryPath}`, error);
445
+ console.error(`Failed to load plugins from ${directoryPath}`, error);
547
446
  }
548
447
  }
549
448
  async disablePlugin(name) {
550
449
  await this.unregister(name);
551
450
  await this.updatePluginState(name, true);
552
- logger.getLogger("PluginManager").info(`Plugin ${name} disabled.`);
451
+ console.log(`Plugin ${name} disabled.`);
553
452
  }
554
453
  async enablePlugin(name) {
555
454
  await this.updatePluginState(name, false);
@@ -559,7 +458,7 @@ export class PluginManager extends EventEmitter {
559
458
  if (plugin.dependencies) {
560
459
  for (const dep of Object.keys(plugin.dependencies)) {
561
460
  if (!this.plugins.has(dep)) {
562
- logger.getLogger("PluginManager").warn(`Cannot enable ${name}: Dependency ${dep} is not loaded.`);
461
+ console.warn(`Cannot enable ${name}: Dependency ${dep} is not loaded.`);
563
462
  return;
564
463
  }
565
464
  }
@@ -567,33 +466,19 @@ export class PluginManager extends EventEmitter {
567
466
  await this.register(plugin);
568
467
  }
569
468
  else {
570
- logger.getLogger("PluginManager").warn(`Plugin ${name} enabled but not found in available plugins.`);
469
+ console.warn(`Plugin ${name} enabled but not found in available plugins.`);
571
470
  }
572
471
  }
573
472
  }
574
473
  async reloadPlugin(name) {
575
- const oldPlugin = this.plugins.get(name);
576
- if (oldPlugin) {
577
- logger.getLogger("PluginManager").info(`Reloading plugin ${name}...`);
474
+ const plugin = this.plugins.get(name);
475
+ if (plugin) {
476
+ console.log(`Reloading plugin ${name}...`);
578
477
  await this.unregister(name);
579
478
  }
580
479
  const definition = this.availablePlugins.get(name);
581
480
  if (definition) {
582
481
  await this.register(definition);
583
- const newPlugin = this.plugins.get(name);
584
- // If the new version has onReload, call it
585
- if (newPlugin && newPlugin.onReload) {
586
- // We need a context for onReload as well
587
- const storage = new JsonPluginStorage(this.storageRoot, name);
588
- const context = createPluginContext(this, newPlugin, this.resources, storage);
589
- try {
590
- await newPlugin.onReload(context);
591
- }
592
- catch (e) {
593
- logger.getLogger("PluginManager").error(`Error in onReload for ${name}:`, e);
594
- }
595
- }
596
- this.emit("plugin:updated", { name: definition.name, version: definition.version });
597
482
  }
598
483
  else {
599
484
  throw new Error(`Plugin ${name} not found in available plugins.`);
@@ -619,7 +504,7 @@ export class PluginManager extends EventEmitter {
619
504
  await Bun.write(globalConfigPath, JSON.stringify(config, null, 2));
620
505
  }
621
506
  catch (e) {
622
- logger.getLogger("PluginManager").error("Failed to update plugin state", e);
507
+ console.error("Failed to update plugin state", e);
623
508
  }
624
509
  }
625
510
  async runOnResolve(args) {
@@ -628,34 +513,158 @@ export class PluginManager extends EventEmitter {
628
513
  async runOnLoad(args) {
629
514
  return this.hooksManager.runOnLoad(args);
630
515
  }
631
- // Bun-like Aliases
632
- async use(plugin) { return this.register(plugin); }
633
- async plugin(plugin) { return this.register(plugin); }
634
- async remove(pluginName) { return this.unregister(pluginName); }
635
516
  toBunPlugin() {
636
517
  return this.hooksManager.toBunPlugin();
637
518
  }
638
- hotReloadTimer = null;
639
519
  enableHotReload(pluginDir) {
640
- logger.getLogger("PluginManager").info(`[HotReload] Watching ${pluginDir} for changes...`);
641
- watch(pluginDir, { recursive: true }, async (event, filename) => {
520
+ // Close existing watcher if any
521
+ if (this.hotReloadWatcher) {
522
+ this.hotReloadWatcher.close();
523
+ }
524
+ // Initial scan to build file map
525
+ this.scanAndTrackPlugins(pluginDir);
526
+ console.log(`[HotReload] Watching ${pluginDir} for changes...`);
527
+ this.hotReloadWatcher = watch(pluginDir, { recursive: true }, async (event, filename) => {
642
528
  if (!filename || (!filename.endsWith(".ts") && !filename.endsWith(".js")))
643
529
  return;
530
+ if (filename.endsWith(".d.ts"))
531
+ return; // Skip type definitions
532
+ const fullPath = join(pluginDir, filename);
644
533
  if (this.hotReloadTimer)
645
534
  clearTimeout(this.hotReloadTimer);
646
535
  this.hotReloadTimer = setTimeout(async () => {
647
- logger.getLogger("PluginManager").info(`[HotReload] Change detected in ${filename}. Re-scanning plugins...`);
648
- await this.loadPluginsFromDirectory(pluginDir);
536
+ await this.handleFileChange(event, fullPath, filename, pluginDir);
649
537
  }, 300);
650
538
  });
651
539
  }
540
+ async scanAndTrackPlugins(pluginDir) {
541
+ this.pluginFiles.clear();
542
+ try {
543
+ const files = await readdir(pluginDir);
544
+ for (const file of files) {
545
+ if ((file.endsWith(".ts") || file.endsWith(".js")) && !file.endsWith(".d.ts")) {
546
+ const fullPath = join(pluginDir, file);
547
+ try {
548
+ const module = await import(fullPath);
549
+ for (const key in module) {
550
+ const ExportedItem = module[key];
551
+ const validation = validatePlugin(ExportedItem);
552
+ if (validation.valid) {
553
+ this.pluginFiles.set(fullPath, validation.plugin.name);
554
+ this.availablePlugins.set(validation.plugin.name, validation.plugin);
555
+ }
556
+ }
557
+ }
558
+ catch (err) {
559
+ console.warn(`[HotReload] Failed to scan ${file}:`, err);
560
+ }
561
+ }
562
+ }
563
+ }
564
+ catch (err) {
565
+ console.error(`[HotReload] Failed to scan plugin directory:`, err);
566
+ }
567
+ }
568
+ async handleFileChange(event, fullPath, filename, pluginDir) {
569
+ const exists = existsSync(fullPath);
570
+ const previousName = this.pluginFiles.get(fullPath);
571
+ if (!exists && previousName) {
572
+ // File was removed - uninstall plugin
573
+ console.log(`[HotReload] Plugin file removed: ${filename}. Unloading plugin ${previousName}...`);
574
+ this.pluginFiles.delete(fullPath);
575
+ if (this.plugins.has(previousName)) {
576
+ await this.unregister(previousName);
577
+ console.log(`[HotReload] Plugin ${previousName} unloaded.`);
578
+ }
579
+ }
580
+ else if (exists && !previousName) {
581
+ // New file added - install plugin
582
+ console.log(event, `[HotReload] New plugin file detected: ${filename}. Loading plugin...`);
583
+ try {
584
+ const module = await import(fullPath);
585
+ for (const key in module) {
586
+ const ExportedItem = module[key];
587
+ const validation = validatePlugin(ExportedItem);
588
+ if (validation.valid) {
589
+ const plugin = validation.plugin;
590
+ this.pluginFiles.set(fullPath, plugin.name);
591
+ this.availablePlugins.set(plugin.name, plugin);
592
+ // Check if not disabled and load it
593
+ const globalConfigPath = join(this.storageRoot, "plugins.json");
594
+ let disabledPlugins = [];
595
+ try {
596
+ const file = Bun.file(globalConfigPath);
597
+ if (await file.exists()) {
598
+ const data = await file.json();
599
+ disabledPlugins = data.disabled || [];
600
+ }
601
+ }
602
+ catch (e) { /* ignore */ }
603
+ if (!disabledPlugins.includes(plugin.name) && !this.plugins.has(plugin.name)) {
604
+ await this.register(plugin);
605
+ console.log(`[HotReload] Plugin ${plugin.name} loaded.`);
606
+ }
607
+ }
608
+ }
609
+ }
610
+ catch (err) {
611
+ console.error(`[HotReload] Failed to load new plugin ${filename}:`, pluginDir, err);
612
+ }
613
+ }
614
+ else if (exists && previousName) {
615
+ // File was modified - reload plugin
616
+ console.log(`[HotReload] Plugin file modified: ${filename}. Reloading plugin ${previousName}...`);
617
+ try {
618
+ // Remove from module cache to force reimport
619
+ delete require.cache[fullPath];
620
+ // Unload existing plugin
621
+ if (this.plugins.has(previousName)) {
622
+ await this.unregister(previousName);
623
+ }
624
+ // Reload the plugin
625
+ const module = await import(fullPath);
626
+ for (const key in module) {
627
+ const ExportedItem = module[key];
628
+ const validation = validatePlugin(ExportedItem);
629
+ if (validation.valid) {
630
+ const plugin = validation.plugin;
631
+ this.availablePlugins.set(plugin.name, plugin);
632
+ // Check if not disabled and load it
633
+ const globalConfigPath = join(this.storageRoot, "plugins.json");
634
+ let disabledPlugins = [];
635
+ try {
636
+ const file = Bun.file(globalConfigPath);
637
+ if (await file.exists()) {
638
+ const data = await file.json();
639
+ disabledPlugins = data.disabled || [];
640
+ }
641
+ }
642
+ catch (e) { /* ignore */ }
643
+ if (!disabledPlugins.includes(plugin.name)) {
644
+ await this.register(plugin);
645
+ console.log(`[HotReload] Plugin ${plugin.name} reloaded.`);
646
+ }
647
+ }
648
+ }
649
+ }
650
+ catch (err) {
651
+ console.error(`[HotReload] Failed to reload plugin ${filename}:`, err);
652
+ }
653
+ }
654
+ }
655
+ disableHotReload() {
656
+ if (this.hotReloadWatcher) {
657
+ this.hotReloadWatcher.close();
658
+ this.hotReloadWatcher = null;
659
+ console.log(`[HotReload] File watcher stopped.`);
660
+ }
661
+ }
652
662
  getMetrics() {
653
663
  return {
654
664
  totalPlugins: this.plugins.size,
655
665
  activePlugins: Array.from(this.plugins.keys()),
656
666
  resources: this.resources.getUsageSummary(),
657
667
  hooks: {
658
- onStart: this.hooksManager.getHookCount(HookType.ON_START),
659
668
  onResolve: this.hooksManager.getHookCount(HookType.ON_RESOLVE),
660
669
  onLoad: this.hooksManager.getHookCount(HookType.ON_LOAD)
661
670
  }
@@ -663,7 +672,7 @@ export class PluginManager extends EventEmitter {
663
672
  }
664
673
  getPluginStatus() {
665
674
  const status = {};
666
- for (const [name, plugin] of Array.from(this.plugins)) {
675
+ for (const [name, plugin] of this.plugins) {
667
676
  const resources = this.resources.get(name);
668
677
  status[name] = {
669
678
  version: plugin.version,
@@ -677,37 +686,5 @@ export class PluginManager extends EventEmitter {
677
686
  }
678
687
  return status;
679
688
  }
680
- async ensureDependenciesInstalled(pluginPath) {
681
- const nodeModulesPath = join(pluginPath, "node_modules");
682
- if (!existsSync(nodeModulesPath)) {
683
- // 1. Check if we are in production
684
- const isProduction = process.env.NODE_ENV === "production";
685
- if (isProduction) {
686
- logger.getLogger("PluginManager").warn(`[PluginManager] Warning: Plugin at ${pluginPath} is missing node_modules. Auto-install is disabled in production.`);
687
- return;
688
- }
689
- // 2. Check if 'bun' CLI is even available in the system
690
- const bunPath = Bun.which("bun");
691
- if (!bunPath) {
692
- logger.getLogger("PluginManager").warn(`[PluginManager] Warning: node_modules missing in ${pluginPath}, but 'bun' CLI was not found. Cannot auto-install.`);
693
- return;
694
- }
695
- logger.getLogger("PluginManager").info(`[PluginManager] Development mode detected. node_modules missing in ${pluginPath}. Installing deps...`);
696
- try {
697
- const proc = Bun.spawn([bunPath, "install"], {
698
- cwd: pluginPath,
699
- stdout: "inherit",
700
- stderr: "inherit",
701
- });
702
- const exitCode = await proc.exited;
703
- if (exitCode !== 0) {
704
- logger.getLogger("PluginManager").error(`[PluginManager] Failed to install dependencies for ${pluginPath}. Exit code: ${exitCode}`);
705
- }
706
- }
707
- catch (e) {
708
- logger.getLogger("PluginManager").error(`[PluginManager] Error running bun install for ${pluginPath}:`, e);
709
- }
710
- }
711
- }
712
689
  }
713
690
  //# sourceMappingURL=PluginManager.js.map