bun_plugins 1.0.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 +81 -0
- package/dist/PluginManager.d.ts +62 -0
- package/dist/PluginManager.d.ts.map +1 -0
- package/dist/PluginManager.js +557 -0
- package/dist/PluginManager.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/managers/ContextFactory.d.ts +6 -0
- package/dist/managers/ContextFactory.d.ts.map +1 -0
- package/dist/managers/ContextFactory.js +109 -0
- package/dist/managers/ContextFactory.js.map +1 -0
- package/dist/managers/DependencyManager.d.ts +10 -0
- package/dist/managers/DependencyManager.d.ts.map +1 -0
- package/dist/managers/DependencyManager.js +94 -0
- package/dist/managers/DependencyManager.js.map +1 -0
- package/dist/managers/HooksManager.d.ts +21 -0
- package/dist/managers/HooksManager.d.ts.map +1 -0
- package/dist/managers/HooksManager.js +117 -0
- package/dist/managers/HooksManager.js.map +1 -0
- package/dist/managers/ResourceManager.d.ts +16 -0
- package/dist/managers/ResourceManager.d.ts.map +1 -0
- package/dist/managers/ResourceManager.js +50 -0
- package/dist/managers/ResourceManager.js.map +1 -0
- package/dist/storage/JsonPluginStorage.d.ts +14 -0
- package/dist/storage/JsonPluginStorage.d.ts.map +1 -0
- package/dist/storage/JsonPluginStorage.js +63 -0
- package/dist/storage/JsonPluginStorage.js.map +1 -0
- package/dist/types.d.ts +167 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +56 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/errorParser.d.ts +3 -0
- package/dist/utils/errorParser.d.ts.map +1 -0
- package/dist/utils/errorParser.js +23 -0
- package/dist/utils/errorParser.js.map +1 -0
- package/dist/utils/pluginValidator.d.ts +47 -0
- package/dist/utils/pluginValidator.d.ts.map +1 -0
- package/dist/utils/pluginValidator.js +76 -0
- package/dist/utils/pluginValidator.js.map +1 -0
- package/dist/utils/security.d.ts +3 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +26 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/worker/WorkerRunner.d.ts +2 -0
- package/dist/worker/WorkerRunner.d.ts.map +1 -0
- package/dist/worker/WorkerRunner.js +254 -0
- package/dist/worker/WorkerRunner.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import {} from "../types";
|
|
2
|
+
import { checkNetworkPermission, checkPermission as checkGeneralPermission } from "../utils/security";
|
|
3
|
+
export function createPluginContext(manager, plugin, resources, storage, config) {
|
|
4
|
+
// We get the resource container directly.
|
|
5
|
+
const pluginResources = resources.get(plugin.name);
|
|
6
|
+
if (!pluginResources)
|
|
7
|
+
throw new Error("Resources not initialized for plugin");
|
|
8
|
+
const checkPermission = (perm, url) => {
|
|
9
|
+
if (perm === 'network' && url) {
|
|
10
|
+
checkNetworkPermission(plugin.name, plugin.permissions, plugin.allowedDomains, url);
|
|
11
|
+
}
|
|
12
|
+
else if (perm === 'filesystem' || perm === 'env') {
|
|
13
|
+
checkGeneralPermission(plugin.name, plugin.permissions, perm);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
manager: manager,
|
|
18
|
+
storage,
|
|
19
|
+
config,
|
|
20
|
+
// Legacy support
|
|
21
|
+
emit: (event, payload) => manager.emit(event, payload),
|
|
22
|
+
on: (event, callback) => {
|
|
23
|
+
manager.on(event, callback);
|
|
24
|
+
pluginResources.eventListeners.push({ event: event, listener: callback });
|
|
25
|
+
},
|
|
26
|
+
events: {
|
|
27
|
+
emit: (event, payload) => manager.emit(event, payload),
|
|
28
|
+
on: (event, callback) => {
|
|
29
|
+
manager.on(event, callback);
|
|
30
|
+
pluginResources.eventListeners.push({ event: event, listener: callback });
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
getPlugin: (name) => {
|
|
34
|
+
const p = manager.getPlugin(name);
|
|
35
|
+
return p?.getSharedApi ? p.getSharedApi() : undefined;
|
|
36
|
+
},
|
|
37
|
+
log: {
|
|
38
|
+
info: (msg, ...args) => console.log(`[${plugin.name}] info: ${msg}`, ...args),
|
|
39
|
+
warn: (msg, ...args) => console.warn(`[${plugin.name}] warn: ${msg}`, ...args),
|
|
40
|
+
error: (msg, ...args) => console.error(`[${plugin.name}] error: ${msg}`, ...args),
|
|
41
|
+
},
|
|
42
|
+
createWorker: (url, options) => {
|
|
43
|
+
// Use the manager's worker factory to allow proper mocking in tests
|
|
44
|
+
const workerFactory = manager.getWorkerFactory();
|
|
45
|
+
const w = workerFactory(url, options);
|
|
46
|
+
// Auto-cleanup when worker closes
|
|
47
|
+
w.addEventListener?.("close", () => {
|
|
48
|
+
const res = resources.get(plugin.name);
|
|
49
|
+
if (res) {
|
|
50
|
+
const index = res.workers.indexOf(w);
|
|
51
|
+
if (index > -1) {
|
|
52
|
+
res.workers.splice(index, 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// Also listen for exit event (Bun specific)
|
|
57
|
+
w.addEventListener?.("exit", () => {
|
|
58
|
+
const res = resources.get(plugin.name);
|
|
59
|
+
if (res) {
|
|
60
|
+
const index = res.workers.indexOf(w);
|
|
61
|
+
if (index > -1) {
|
|
62
|
+
res.workers.splice(index, 1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
w.addEventListener?.("error", (err) => {
|
|
67
|
+
console.error(`[${plugin.name}] Worker error:`, err.message);
|
|
68
|
+
});
|
|
69
|
+
resources.get(plugin.name)?.workers.push(w);
|
|
70
|
+
return w;
|
|
71
|
+
},
|
|
72
|
+
setTimeout: (callback, delay, ...args) => {
|
|
73
|
+
const id = setTimeout(callback, delay, ...args);
|
|
74
|
+
resources.get(plugin.name)?.timers.push({ id, type: 'timeout' });
|
|
75
|
+
return id;
|
|
76
|
+
},
|
|
77
|
+
setInterval: (callback, delay, ...args) => {
|
|
78
|
+
const id = setInterval(callback, delay, ...args);
|
|
79
|
+
resources.get(plugin.name)?.timers.push({ id, type: 'interval' });
|
|
80
|
+
return id;
|
|
81
|
+
},
|
|
82
|
+
clearTimeout: (id) => {
|
|
83
|
+
clearTimeout(id);
|
|
84
|
+
// Removing from list logic omitted for speed, cleanup handles remainder
|
|
85
|
+
},
|
|
86
|
+
clearInterval: (id) => {
|
|
87
|
+
clearInterval(id);
|
|
88
|
+
},
|
|
89
|
+
network: {
|
|
90
|
+
fetch: (input, init) => {
|
|
91
|
+
const urlStr = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
|
|
92
|
+
checkPermission('network', urlStr);
|
|
93
|
+
return fetch(input, init);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
file: (path) => {
|
|
97
|
+
checkPermission('filesystem');
|
|
98
|
+
return Bun.file(path);
|
|
99
|
+
},
|
|
100
|
+
get env() {
|
|
101
|
+
checkPermission('env');
|
|
102
|
+
return new Proxy(process.env, {
|
|
103
|
+
get(target, prop) { return Reflect.get(target, prop); },
|
|
104
|
+
set() { throw new Error("Plugins cannot modify environment variables."); }
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=ContextFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextFactory.js","sourceRoot":"","sources":["../../src/managers/ContextFactory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IPlugin } from "../types";
|
|
2
|
+
export declare class DependencyManager {
|
|
3
|
+
/**
|
|
4
|
+
* Topologically sort plugins based on dependencies.
|
|
5
|
+
* Throws if circular dependency detected.
|
|
6
|
+
*/
|
|
7
|
+
resolveLoadOrder(plugins: IPlugin[]): IPlugin[];
|
|
8
|
+
validateDependencies(plugin: IPlugin, loadedPlugins: Map<string, IPlugin>): void;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=DependencyManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DependencyManager.d.ts","sourceRoot":"","sources":["../../src/managers/DependencyManager.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxC,qBAAa,iBAAiB;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE;IAiF/C,oBAAoB,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAcnF"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import semver from "semver";
|
|
2
|
+
export class DependencyManager {
|
|
3
|
+
/**
|
|
4
|
+
* Topologically sort plugins based on dependencies.
|
|
5
|
+
* Throws if circular dependency detected.
|
|
6
|
+
*/
|
|
7
|
+
resolveLoadOrder(plugins) {
|
|
8
|
+
const g = new Map();
|
|
9
|
+
const pluginMap = new Map();
|
|
10
|
+
// Initialize graph
|
|
11
|
+
for (const p of plugins) {
|
|
12
|
+
pluginMap.set(p.name, p);
|
|
13
|
+
g.set(p.name, []);
|
|
14
|
+
}
|
|
15
|
+
// Build edges
|
|
16
|
+
for (const p of plugins) {
|
|
17
|
+
if (p.dependencies) {
|
|
18
|
+
for (const depName of Object.keys(p.dependencies)) {
|
|
19
|
+
if (pluginMap.has(depName)) {
|
|
20
|
+
g.get(p.name).push(depName);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
// We skip missing dependencies here as strict validation might happen elsewhere,
|
|
24
|
+
// or we throw if strictness is required during sort.
|
|
25
|
+
// For this implementation, we throw if dependency is declared but not present in the set to sort.
|
|
26
|
+
// However, commonly we might only be sorting a subset.
|
|
27
|
+
// Let's assume strictness for the provided set.
|
|
28
|
+
// Actually, looking at original code: it throws if not enabled or found.
|
|
29
|
+
// We might want to allow sorting even if deps are external (already loaded).
|
|
30
|
+
// But here we received `plugins` as "plugins to load".
|
|
31
|
+
// Logic refactor: If dependent is not in list, maybe it is already loaded?
|
|
32
|
+
// The original code checked `this.plugins.has(depName)` (already loaded).
|
|
33
|
+
// We'll trust the caller to handle external checks or we need to pass `loadedPlugins` map.
|
|
34
|
+
// For pure topological sort of a batch, we just sort the batch.
|
|
35
|
+
// If A depends on B, and B is not in batch, we assume B is effectively "root" relative to this batch
|
|
36
|
+
// (i.e., we don't add an edge to it within this graph).
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Output logic: Dependency -> Dependent
|
|
42
|
+
// Using Kahn's algorithm or similar.
|
|
43
|
+
const inDegree = new Map();
|
|
44
|
+
for (const name of pluginMap.keys())
|
|
45
|
+
inDegree.set(name, 0);
|
|
46
|
+
const adj = new Map();
|
|
47
|
+
for (const name of pluginMap.keys())
|
|
48
|
+
adj.set(name, []);
|
|
49
|
+
for (const [pName, deps] of g.entries()) {
|
|
50
|
+
for (const depName of deps) {
|
|
51
|
+
// depName -> pName
|
|
52
|
+
if (adj.has(depName)) {
|
|
53
|
+
adj.get(depName).push(pName);
|
|
54
|
+
inDegree.set(pName, (inDegree.get(pName) || 0) + 1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const queue = [];
|
|
59
|
+
for (const [name, deg] of inDegree.entries()) {
|
|
60
|
+
if (deg === 0)
|
|
61
|
+
queue.push(name);
|
|
62
|
+
}
|
|
63
|
+
const sorted = [];
|
|
64
|
+
while (queue.length > 0) {
|
|
65
|
+
const u = queue.shift();
|
|
66
|
+
sorted.push(pluginMap.get(u));
|
|
67
|
+
for (const v of adj.get(u) || []) {
|
|
68
|
+
inDegree.set(v, inDegree.get(v) - 1);
|
|
69
|
+
if (inDegree.get(v) === 0) {
|
|
70
|
+
queue.push(v);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (sorted.length !== plugins.length) {
|
|
75
|
+
throw new Error("Circular dependency detected in plugins.");
|
|
76
|
+
}
|
|
77
|
+
return sorted;
|
|
78
|
+
}
|
|
79
|
+
validateDependencies(plugin, loadedPlugins) {
|
|
80
|
+
if (plugin.dependencies) {
|
|
81
|
+
for (const [depName, requiredVersion] of Object.entries(plugin.dependencies)) {
|
|
82
|
+
const depPlugin = loadedPlugins.get(depName);
|
|
83
|
+
if (!depPlugin) {
|
|
84
|
+
throw new Error(`Plugin ${plugin.name} requires missing dependency: ${depName} (${requiredVersion})`);
|
|
85
|
+
}
|
|
86
|
+
// Version check using semver
|
|
87
|
+
if (!semver.satisfies(depPlugin.version, requiredVersion)) {
|
|
88
|
+
throw new Error(`Plugin ${plugin.name} requires dependency ${depName} version ${requiredVersion}, but found ${depPlugin.version}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=DependencyManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DependencyManager.js","sourceRoot":"","sources":["../../src/managers/DependencyManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type OnResolveCallback, type OnLoadCallback, type OnResolveArgs, type OnLoadArgs, type PluginBuilder, HookOrder, HookType } from "../types";
|
|
2
|
+
import type { BunPlugin } from "bun";
|
|
3
|
+
export declare class HooksManager {
|
|
4
|
+
private onResolveHooks;
|
|
5
|
+
private onLoadHooks;
|
|
6
|
+
registerOnResolve(filter: RegExp, callback: OnResolveCallback, pluginName: string, order?: HookOrder): void;
|
|
7
|
+
registerOnLoad(filter: RegExp, callback: OnLoadCallback, pluginName: string, order?: HookOrder): void;
|
|
8
|
+
getHookCount(type: HookType): number;
|
|
9
|
+
cleanup(pluginName: string): void;
|
|
10
|
+
runOnResolve(args: OnResolveArgs): Promise<{
|
|
11
|
+
path: string;
|
|
12
|
+
namespace?: string;
|
|
13
|
+
} | null>;
|
|
14
|
+
runOnLoad(args: OnLoadArgs): Promise<{
|
|
15
|
+
contents?: string;
|
|
16
|
+
loader?: string;
|
|
17
|
+
} | null>;
|
|
18
|
+
getBuilder(pluginName: string): PluginBuilder;
|
|
19
|
+
toBunPlugin(): BunPlugin;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=HooksManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HooksManager.d.ts","sourceRoot":"","sources":["../../src/managers/HooksManager.ts"],"names":[],"mappings":"AACA,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,UAAU,EAEf,KAAK,aAAa,EAClB,SAAS,EACT,QAAQ,EACX,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAErC,qBAAa,YAAY;IACrB,OAAO,CAAC,cAAc,CAAyC;IAC/D,OAAO,CAAC,WAAW,CAAsC;IAEzD,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS;IAMpG,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS;IAI9F,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM;IAIpC,OAAO,CAAC,UAAU,EAAE,MAAM;IAKpB,YAAY,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAmBvF,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAgCzF,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa;IAyB7C,WAAW,IAAI,SAAS;CAsB3B"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { HookOrder, HookType } from "../types";
|
|
2
|
+
export class HooksManager {
|
|
3
|
+
onResolveHooks = [];
|
|
4
|
+
onLoadHooks = [];
|
|
5
|
+
registerOnResolve(filter, callback, pluginName, order) {
|
|
6
|
+
// Performance wrapper could be applied here or by caller.
|
|
7
|
+
// For simplicity, we store as is.
|
|
8
|
+
this.onResolveHooks.push({ filter, callback, pluginName, order });
|
|
9
|
+
}
|
|
10
|
+
registerOnLoad(filter, callback, pluginName, order) {
|
|
11
|
+
this.onLoadHooks.push({ filter, callback, pluginName, order });
|
|
12
|
+
}
|
|
13
|
+
getHookCount(type) {
|
|
14
|
+
return type === HookType.ON_RESOLVE ? this.onResolveHooks.length : this.onLoadHooks.length;
|
|
15
|
+
}
|
|
16
|
+
cleanup(pluginName) {
|
|
17
|
+
this.onResolveHooks = this.onResolveHooks.filter(h => h.pluginName !== pluginName);
|
|
18
|
+
this.onLoadHooks = this.onLoadHooks.filter(h => h.pluginName !== pluginName);
|
|
19
|
+
}
|
|
20
|
+
async runOnResolve(args) {
|
|
21
|
+
const sortedHooks = [...this.onResolveHooks].sort((a, b) => {
|
|
22
|
+
const score = (o) => o === HookOrder.PRE ? -1 : o === HookOrder.POST ? 1 : 0;
|
|
23
|
+
return score(a.order) - score(b.order);
|
|
24
|
+
});
|
|
25
|
+
for (const hook of sortedHooks) {
|
|
26
|
+
if (hook.filter.test(args.path)) {
|
|
27
|
+
try {
|
|
28
|
+
const result = await hook.callback(args);
|
|
29
|
+
if (result)
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
console.error(`Error in onResolve hook from ${hook.pluginName}:`, e);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
async runOnLoad(args) {
|
|
40
|
+
const sortedHooks = [...this.onLoadHooks].sort((a, b) => {
|
|
41
|
+
const score = (o) => o === HookOrder.PRE ? -1 : o === HookOrder.POST ? 1 : 0;
|
|
42
|
+
return score(a.order) - score(b.order);
|
|
43
|
+
});
|
|
44
|
+
let currentResult = null;
|
|
45
|
+
let pipelineContents = undefined;
|
|
46
|
+
for (const hook of sortedHooks) {
|
|
47
|
+
if (hook.filter.test(args.path)) {
|
|
48
|
+
const hookArgs = { ...args, previousContents: pipelineContents };
|
|
49
|
+
try {
|
|
50
|
+
const result = await hook.callback(hookArgs);
|
|
51
|
+
if (result) {
|
|
52
|
+
if (result.contents !== undefined) {
|
|
53
|
+
pipelineContents = result.contents;
|
|
54
|
+
}
|
|
55
|
+
currentResult = {
|
|
56
|
+
...(currentResult || {}),
|
|
57
|
+
...result,
|
|
58
|
+
contents: pipelineContents
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
console.error(`Error in onLoad hook from ${hook.pluginName}:`, e);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return currentResult;
|
|
68
|
+
}
|
|
69
|
+
getBuilder(pluginName) {
|
|
70
|
+
return {
|
|
71
|
+
onResolve: (filter, callback, options) => {
|
|
72
|
+
const perfCallback = async (args) => {
|
|
73
|
+
const start = performance.now();
|
|
74
|
+
const res = await callback(args);
|
|
75
|
+
const dur = performance.now() - start;
|
|
76
|
+
if (dur > 100)
|
|
77
|
+
console.warn(`[Performance] ${pluginName} onResolve took ${dur.toFixed(2)}ms`);
|
|
78
|
+
return res;
|
|
79
|
+
};
|
|
80
|
+
this.registerOnResolve(filter, perfCallback, pluginName, options?.order);
|
|
81
|
+
},
|
|
82
|
+
onLoad: (filter, callback, options) => {
|
|
83
|
+
const perfCallback = async (args) => {
|
|
84
|
+
const start = performance.now();
|
|
85
|
+
const res = await callback(args);
|
|
86
|
+
const dur = performance.now() - start;
|
|
87
|
+
if (dur > 100)
|
|
88
|
+
console.warn(`[Performance] ${pluginName} onLoad took ${dur.toFixed(2)}ms`);
|
|
89
|
+
return res;
|
|
90
|
+
};
|
|
91
|
+
this.registerOnLoad(filter, perfCallback, pluginName, options?.order);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
toBunPlugin() {
|
|
96
|
+
return {
|
|
97
|
+
name: "BunPluginManagerBridge",
|
|
98
|
+
setup: (build) => {
|
|
99
|
+
// Use a catch-all filter to allow dynamic hook registration
|
|
100
|
+
build.onResolve({ filter: /.*/ }, async (args) => {
|
|
101
|
+
return this.runOnResolve(args);
|
|
102
|
+
});
|
|
103
|
+
build.onLoad({ filter: /.*/ }, async (args) => {
|
|
104
|
+
const res = await this.runOnLoad(args);
|
|
105
|
+
if (res && res.contents !== undefined) {
|
|
106
|
+
return {
|
|
107
|
+
contents: res.contents,
|
|
108
|
+
loader: res.loader
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=HooksManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HooksManager.js","sourceRoot":"","sources":["../../src/managers/HooksManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type PluginResource } from "../types";
|
|
2
|
+
export declare class ResourceManager {
|
|
3
|
+
private resources;
|
|
4
|
+
init(pluginName: string): PluginResource;
|
|
5
|
+
get(pluginName: string): PluginResource | undefined;
|
|
6
|
+
cleanup(pluginName: string, eventEmitter?: {
|
|
7
|
+
off: (e: string, l: any) => void;
|
|
8
|
+
}): void;
|
|
9
|
+
getUsageSummary(): {
|
|
10
|
+
totalWorkers: number;
|
|
11
|
+
totalTimers: number;
|
|
12
|
+
totalListeners: number;
|
|
13
|
+
pluginCount: number;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ResourceManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceManager.d.ts","sourceRoot":"","sources":["../../src/managers/ResourceManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,qBAAa,eAAe;IACxB,OAAO,CAAC,SAAS,CAA0C;IAE3D,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc;IAMxC,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAInD,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE;QAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,KAAK,IAAI,CAAA;KAAE;IAoB/E,eAAe;;;;;;CAkBlB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import {} from "../types";
|
|
2
|
+
export class ResourceManager {
|
|
3
|
+
resources = new Map();
|
|
4
|
+
init(pluginName) {
|
|
5
|
+
const res = { workers: [], timers: [], eventListeners: [] };
|
|
6
|
+
this.resources.set(pluginName, res);
|
|
7
|
+
return res;
|
|
8
|
+
}
|
|
9
|
+
get(pluginName) {
|
|
10
|
+
return this.resources.get(pluginName);
|
|
11
|
+
}
|
|
12
|
+
cleanup(pluginName, eventEmitter) {
|
|
13
|
+
const res = this.resources.get(pluginName);
|
|
14
|
+
if (res) {
|
|
15
|
+
for (const worker of res.workers) {
|
|
16
|
+
console.log(`Terminating worker for plugin ${pluginName}`);
|
|
17
|
+
worker.terminate();
|
|
18
|
+
}
|
|
19
|
+
for (const timer of res.timers) {
|
|
20
|
+
if (timer.type === 'timeout')
|
|
21
|
+
clearTimeout(timer.id);
|
|
22
|
+
if (timer.type === 'interval')
|
|
23
|
+
clearInterval(timer.id);
|
|
24
|
+
}
|
|
25
|
+
if (eventEmitter) {
|
|
26
|
+
for (const listener of res.eventListeners) {
|
|
27
|
+
eventEmitter.off(listener.event, listener.listener);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
this.resources.delete(pluginName);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
getUsageSummary() {
|
|
34
|
+
let totalWorkers = 0;
|
|
35
|
+
let totalTimers = 0;
|
|
36
|
+
let totalListeners = 0;
|
|
37
|
+
for (const res of this.resources.values()) {
|
|
38
|
+
totalWorkers += res.workers.length;
|
|
39
|
+
totalTimers += res.timers.length;
|
|
40
|
+
totalListeners += res.eventListeners.length;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
totalWorkers,
|
|
44
|
+
totalTimers,
|
|
45
|
+
totalListeners,
|
|
46
|
+
pluginCount: this.resources.size
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=ResourceManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResourceManager.js","sourceRoot":"","sources":["../../src/managers/ResourceManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,MAAM,UAAU,CAAC;AAE/C,MAAM,OAAO,eAAe;IAChB,SAAS,GAAgC,IAAI,GAAG,EAAE,CAAC;IAE3D,IAAI,CAAC,UAAkB;QACnB,MAAM,GAAG,GAAmB,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC;QAC5E,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACpC,OAAO,GAAG,CAAC;IACf,CAAC;IAED,GAAG,CAAC,UAAkB;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CAAC,UAAkB,EAAE,YAAmD;QAC3E,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,GAAG,EAAE,CAAC;YACN,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,iCAAiC,UAAU,EAAE,CAAC,CAAC;gBAC3D,MAAM,CAAC,SAAS,EAAE,CAAC;YACvB,CAAC;YACD,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;gBAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;oBAAE,YAAY,CAAC,KAAK,CAAC,EAAY,CAAC,CAAC;gBAC/D,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU;oBAAE,aAAa,CAAC,KAAK,CAAC,EAAY,CAAC,CAAC;YACrE,CAAC;YACD,IAAI,YAAY,EAAE,CAAC;gBACf,KAAK,MAAM,QAAQ,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;oBACxC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,QAAe,CAAC,CAAC;gBAC/D,CAAC;YACL,CAAC;YACD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACtC,CAAC;IACL,CAAC;IAED,eAAe;QACX,IAAI,YAAY,GAAG,CAAC,CAAC;QACrB,IAAI,WAAW,GAAG,CAAC,CAAC;QACpB,IAAI,cAAc,GAAG,CAAC,CAAC;QAEvB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,YAAY,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;YACnC,WAAW,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;YACjC,cAAc,IAAI,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC;QAChD,CAAC;QAED,OAAO;YACH,YAAY;YACZ,WAAW;YACX,cAAc;YACd,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI;SACnC,CAAC;IACN,CAAC;CACJ"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IPluginStorage } from "../types";
|
|
2
|
+
export declare class JsonPluginStorage implements IPluginStorage {
|
|
3
|
+
private filePath;
|
|
4
|
+
private data;
|
|
5
|
+
private basePath;
|
|
6
|
+
constructor(basePath: string, pluginName: string);
|
|
7
|
+
private ensureLoaded;
|
|
8
|
+
private save;
|
|
9
|
+
get<T>(key: string, defaultValue?: T): Promise<T | undefined>;
|
|
10
|
+
set<T>(key: string, value: T): Promise<void>;
|
|
11
|
+
delete(key: string): Promise<void>;
|
|
12
|
+
clear(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=JsonPluginStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonPluginStorage.d.ts","sourceRoot":"","sources":["../../src/storage/JsonPluginStorage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE/C,qBAAa,iBAAkB,YAAW,cAAc;IACtD,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAoC;IAChD,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;YAKlC,YAAY;YAeZ,IAAI;IAWZ,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAK7D,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ5C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { join, dirname } from "node:path";
|
|
2
|
+
import { mkdir } from "node:fs/promises";
|
|
3
|
+
export class JsonPluginStorage {
|
|
4
|
+
filePath;
|
|
5
|
+
data = null;
|
|
6
|
+
basePath;
|
|
7
|
+
constructor(basePath, pluginName) {
|
|
8
|
+
this.basePath = basePath;
|
|
9
|
+
this.filePath = join(basePath, "plugins", pluginName, "storage.json");
|
|
10
|
+
}
|
|
11
|
+
async ensureLoaded() {
|
|
12
|
+
if (this.data !== null)
|
|
13
|
+
return;
|
|
14
|
+
try {
|
|
15
|
+
const file = Bun.file(this.filePath);
|
|
16
|
+
if (await file.exists()) {
|
|
17
|
+
this.data = await file.json();
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
this.data = {};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
console.error(`Failed to load storage for ${this.filePath}`, e);
|
|
25
|
+
this.data = {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async save() {
|
|
29
|
+
if (this.data === null)
|
|
30
|
+
return;
|
|
31
|
+
try {
|
|
32
|
+
// Ensure directory exists
|
|
33
|
+
await mkdir(dirname(this.filePath), { recursive: true });
|
|
34
|
+
await Bun.write(this.filePath, JSON.stringify(this.data, null, 2));
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
console.error(`Failed to save storage for ${this.filePath}`, e);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async get(key, defaultValue) {
|
|
41
|
+
await this.ensureLoaded();
|
|
42
|
+
return this.data?.[key] ?? defaultValue;
|
|
43
|
+
}
|
|
44
|
+
async set(key, value) {
|
|
45
|
+
await this.ensureLoaded();
|
|
46
|
+
if (this.data) {
|
|
47
|
+
this.data[key] = value;
|
|
48
|
+
await this.save();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async delete(key) {
|
|
52
|
+
await this.ensureLoaded();
|
|
53
|
+
if (this.data) {
|
|
54
|
+
delete this.data[key];
|
|
55
|
+
await this.save();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async clear() {
|
|
59
|
+
this.data = {};
|
|
60
|
+
await this.save();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=JsonPluginStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"JsonPluginStorage.js","sourceRoot":"","sources":["../../src/storage/JsonPluginStorage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGzC,MAAM,OAAO,iBAAiB;IACpB,QAAQ,CAAS;IACjB,IAAI,GAA+B,IAAI,CAAC;IACxC,QAAQ,CAAS;IAEzB,YAAY,QAAgB,EAAE,UAAkB;QAC9C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC;IACxE,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO;QAC/B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACrC,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBACxB,IAAI,CAAC,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;YACjB,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,8BAA8B,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;YAChE,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,OAAO;QAC/B,IAAI,CAAC;YACD,0BAA0B;YAC1B,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACzD,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,8BAA8B,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,YAAgB;QACxC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,OAAQ,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAO,IAAI,YAAY,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,KAAQ;QAChC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACvB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACZ,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACtB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC;QACf,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACpB,CAAC;CACF"}
|