fluxplugin 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/LICENSE +9 -0
- package/README.md +50 -0
- package/dist/browser/chunks/chunk-Q75AOCXD.js +2544 -0
- package/dist/browser/chunks/chunk-ZZ25CRMR.js +759 -0
- package/dist/browser/index.js +138 -0
- package/dist/browser/manager-ui.js +165 -0
- package/dist/browser/react.js +73 -0
- package/dist/cli.js +1635 -0
- package/dist/node/chunks/chunk-BZ7NZF7I.js +990 -0
- package/dist/node/chunks/chunk-XPLGAEBH.js +2623 -0
- package/dist/node/cli-api.js +843 -0
- package/dist/node/index.js +138 -0
- package/dist/node/main.js +61 -0
- package/dist/node/preload.js +56 -0
- package/dist/types/cli/bin.d.ts +1 -0
- package/dist/types/cli/build.d.ts +7 -0
- package/dist/types/cli/cli.d.ts +2 -0
- package/dist/types/cli/config.d.ts +9 -0
- package/dist/types/cli/host-templates.d.ts +6 -0
- package/dist/types/cli/host.d.ts +16 -0
- package/dist/types/cli/index.d.ts +6 -0
- package/dist/types/cli/shared-modules.d.ts +8 -0
- package/dist/types/cli/templates.d.ts +10 -0
- package/dist/types/core/api.d.ts +11 -0
- package/dist/types/core/common.d.ts +69 -0
- package/dist/types/core/deps.d.ts +34 -0
- package/dist/types/core/events.d.ts +58 -0
- package/dist/types/core/hooks.d.ts +55 -0
- package/dist/types/core/index.d.ts +18 -0
- package/dist/types/core/ipc.d.ts +148 -0
- package/dist/types/core/manager.d.ts +155 -0
- package/dist/types/core/manifest.d.ts +88 -0
- package/dist/types/core/permissions.d.ts +45 -0
- package/dist/types/core/plugin.d.ts +214 -0
- package/dist/types/core/protocol.d.ts +86 -0
- package/dist/types/core/registry.d.ts +88 -0
- package/dist/types/core/routes.d.ts +105 -0
- package/dist/types/core/schema.d.ts +99 -0
- package/dist/types/core/semver.d.ts +16 -0
- package/dist/types/core/slots.d.ts +75 -0
- package/dist/types/core/storage.d.ts +55 -0
- package/dist/types/core/styles.d.ts +34 -0
- package/dist/types/main/adapters.d.ts +81 -0
- package/dist/types/main/discover.d.ts +21 -0
- package/dist/types/main/framework.d.ts +78 -0
- package/dist/types/main/fs-storage.d.ts +33 -0
- package/dist/types/main/index.d.ts +8 -0
- package/dist/types/main/registry.d.ts +75 -0
- package/dist/types/main/security.d.ts +24 -0
- package/dist/types/main/serve-web.d.ts +14 -0
- package/dist/types/main/tar.d.ts +10 -0
- package/dist/types/manager-ui/index.d.ts +7 -0
- package/dist/types/preload/index.d.ts +27 -0
- package/dist/types/react/base-css.d.ts +2 -0
- package/dist/types/react/components.d.ts +89 -0
- package/dist/types/react/http-bridge.d.ts +10 -0
- package/dist/types/react/index.d.ts +6 -0
- package/dist/types/react/palette.d.ts +10 -0
- package/dist/types/react/router.d.ts +47 -0
- package/dist/types/react/runtime.d.ts +99 -0
- package/docs/ARCHITECTURE.md +31 -0
- package/docs/PLUGIN-AUTHORS.md +11 -0
- package/docs/RELEASE.md +20 -0
- package/docs/SECURITY.md +18 -0
- package/docs/screenshots/command-palette.png +0 -0
- package/docs/screenshots/dashboard.png +0 -0
- package/docs/screenshots/plugin-details.png +0 -0
- package/docs/screenshots/plugin-manager.png +0 -0
- package/docs/screenshots/stats.png +0 -0
- package/package.json +112 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BUILTIN_PERMISSIONS,
|
|
3
|
+
CHANNELS,
|
|
4
|
+
CommandRegistry,
|
|
5
|
+
DisposableStore,
|
|
6
|
+
EventBus,
|
|
7
|
+
ExtensionPointRegistry,
|
|
8
|
+
FRAMEWORK_ENGINE_KEY,
|
|
9
|
+
FRAMEWORK_VERSION,
|
|
10
|
+
FrameworkError,
|
|
11
|
+
HookCancelledError,
|
|
12
|
+
HookSystem,
|
|
13
|
+
IpcError,
|
|
14
|
+
IpcRegistry,
|
|
15
|
+
LifecycleError,
|
|
16
|
+
LogStore,
|
|
17
|
+
MGMT,
|
|
18
|
+
MemoryStorageBackend,
|
|
19
|
+
MenuRegistry,
|
|
20
|
+
PermissionDeniedError,
|
|
21
|
+
PermissionManager,
|
|
22
|
+
PluginManager,
|
|
23
|
+
PreloadRegistry,
|
|
24
|
+
Registry,
|
|
25
|
+
RouteRegistry,
|
|
26
|
+
ServiceRegistry,
|
|
27
|
+
SlotRegistry,
|
|
28
|
+
StyleRegistry,
|
|
29
|
+
TimeoutError,
|
|
30
|
+
ValidationError,
|
|
31
|
+
activationOrderFor,
|
|
32
|
+
buildDependencyGraph,
|
|
33
|
+
compareVersions,
|
|
34
|
+
createPluginConfig,
|
|
35
|
+
createPluginState,
|
|
36
|
+
createPluginStorage,
|
|
37
|
+
defineCommand,
|
|
38
|
+
defineComponent,
|
|
39
|
+
defineEvent,
|
|
40
|
+
defineHook,
|
|
41
|
+
defineIPC,
|
|
42
|
+
defineIpcContract,
|
|
43
|
+
defineMenu,
|
|
44
|
+
definePlugin,
|
|
45
|
+
defineRoute,
|
|
46
|
+
defineService,
|
|
47
|
+
dependentsOf,
|
|
48
|
+
describeIssue,
|
|
49
|
+
errorMessage,
|
|
50
|
+
hasPluginApi,
|
|
51
|
+
isValidRange,
|
|
52
|
+
isValidVersion,
|
|
53
|
+
manifestSchema,
|
|
54
|
+
matchesPattern,
|
|
55
|
+
menuLocations,
|
|
56
|
+
normalizePath,
|
|
57
|
+
parseOrThrow,
|
|
58
|
+
parseVersion,
|
|
59
|
+
pluginApi,
|
|
60
|
+
preloadMember,
|
|
61
|
+
routePatternMatches,
|
|
62
|
+
s,
|
|
63
|
+
satisfies,
|
|
64
|
+
scopeCss,
|
|
65
|
+
serializeError,
|
|
66
|
+
toDisposable,
|
|
67
|
+
validateManifest,
|
|
68
|
+
withTimeout
|
|
69
|
+
} from "./chunks/chunk-XPLGAEBH.js";
|
|
70
|
+
export {
|
|
71
|
+
BUILTIN_PERMISSIONS,
|
|
72
|
+
CHANNELS,
|
|
73
|
+
CommandRegistry,
|
|
74
|
+
DisposableStore,
|
|
75
|
+
EventBus,
|
|
76
|
+
ExtensionPointRegistry,
|
|
77
|
+
FRAMEWORK_ENGINE_KEY,
|
|
78
|
+
FRAMEWORK_VERSION,
|
|
79
|
+
FrameworkError,
|
|
80
|
+
HookCancelledError,
|
|
81
|
+
HookSystem,
|
|
82
|
+
IpcError,
|
|
83
|
+
IpcRegistry,
|
|
84
|
+
LifecycleError,
|
|
85
|
+
LogStore,
|
|
86
|
+
MGMT,
|
|
87
|
+
MemoryStorageBackend,
|
|
88
|
+
MenuRegistry,
|
|
89
|
+
PermissionDeniedError,
|
|
90
|
+
PermissionManager,
|
|
91
|
+
PluginManager,
|
|
92
|
+
PreloadRegistry,
|
|
93
|
+
Registry,
|
|
94
|
+
RouteRegistry,
|
|
95
|
+
ServiceRegistry,
|
|
96
|
+
SlotRegistry,
|
|
97
|
+
StyleRegistry,
|
|
98
|
+
TimeoutError,
|
|
99
|
+
ValidationError,
|
|
100
|
+
activationOrderFor,
|
|
101
|
+
buildDependencyGraph,
|
|
102
|
+
compareVersions,
|
|
103
|
+
createPluginConfig,
|
|
104
|
+
createPluginState,
|
|
105
|
+
createPluginStorage,
|
|
106
|
+
defineCommand,
|
|
107
|
+
defineComponent,
|
|
108
|
+
defineEvent,
|
|
109
|
+
defineHook,
|
|
110
|
+
defineIPC,
|
|
111
|
+
defineIpcContract,
|
|
112
|
+
defineMenu,
|
|
113
|
+
definePlugin,
|
|
114
|
+
defineRoute,
|
|
115
|
+
defineService,
|
|
116
|
+
dependentsOf,
|
|
117
|
+
describeIssue,
|
|
118
|
+
errorMessage,
|
|
119
|
+
hasPluginApi,
|
|
120
|
+
isValidRange,
|
|
121
|
+
isValidVersion,
|
|
122
|
+
manifestSchema,
|
|
123
|
+
matchesPattern,
|
|
124
|
+
menuLocations,
|
|
125
|
+
normalizePath,
|
|
126
|
+
parseOrThrow,
|
|
127
|
+
parseVersion,
|
|
128
|
+
pluginApi,
|
|
129
|
+
preloadMember,
|
|
130
|
+
routePatternMatches,
|
|
131
|
+
s,
|
|
132
|
+
satisfies,
|
|
133
|
+
scopeCss,
|
|
134
|
+
serializeError,
|
|
135
|
+
toDisposable,
|
|
136
|
+
validateManifest,
|
|
137
|
+
withTimeout
|
|
138
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FsStorageBackend,
|
|
3
|
+
HttpRegistry,
|
|
4
|
+
IntegrityError,
|
|
5
|
+
JsonStateFile,
|
|
6
|
+
LocalRegistry,
|
|
7
|
+
MANIFEST_FILE,
|
|
8
|
+
MainFramework,
|
|
9
|
+
PLUGIN_SCHEME,
|
|
10
|
+
PluginInstaller,
|
|
11
|
+
attachElectron,
|
|
12
|
+
attachHttp,
|
|
13
|
+
canonicalJson,
|
|
14
|
+
computeIntegrity,
|
|
15
|
+
copyDir,
|
|
16
|
+
createLoopbackBridge,
|
|
17
|
+
createTarGz,
|
|
18
|
+
discoverPlugins,
|
|
19
|
+
extractTarGz,
|
|
20
|
+
generateSigningKeyPair,
|
|
21
|
+
importFresh,
|
|
22
|
+
readPluginDir,
|
|
23
|
+
readTarGz,
|
|
24
|
+
registerPluginProtocol,
|
|
25
|
+
resolvePluginAsset,
|
|
26
|
+
serveWeb,
|
|
27
|
+
sha256File,
|
|
28
|
+
signManifest,
|
|
29
|
+
verifyPlugin
|
|
30
|
+
} from "./chunks/chunk-BZ7NZF7I.js";
|
|
31
|
+
import "./chunks/chunk-XPLGAEBH.js";
|
|
32
|
+
export {
|
|
33
|
+
FsStorageBackend,
|
|
34
|
+
HttpRegistry,
|
|
35
|
+
IntegrityError,
|
|
36
|
+
JsonStateFile,
|
|
37
|
+
LocalRegistry,
|
|
38
|
+
MANIFEST_FILE,
|
|
39
|
+
MainFramework,
|
|
40
|
+
PLUGIN_SCHEME,
|
|
41
|
+
PluginInstaller,
|
|
42
|
+
attachElectron,
|
|
43
|
+
attachHttp,
|
|
44
|
+
canonicalJson,
|
|
45
|
+
computeIntegrity,
|
|
46
|
+
copyDir,
|
|
47
|
+
createLoopbackBridge,
|
|
48
|
+
createTarGz,
|
|
49
|
+
discoverPlugins,
|
|
50
|
+
extractTarGz,
|
|
51
|
+
generateSigningKeyPair,
|
|
52
|
+
importFresh,
|
|
53
|
+
readPluginDir,
|
|
54
|
+
readTarGz,
|
|
55
|
+
registerPluginProtocol,
|
|
56
|
+
resolvePluginAsset,
|
|
57
|
+
serveWeb,
|
|
58
|
+
sha256File,
|
|
59
|
+
signManifest,
|
|
60
|
+
verifyPlugin
|
|
61
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CHANNELS
|
|
3
|
+
} from "./chunks/chunk-XPLGAEBH.js";
|
|
4
|
+
|
|
5
|
+
// src/preload/index.ts
|
|
6
|
+
var IpcCallError = class extends Error {
|
|
7
|
+
constructor(payload) {
|
|
8
|
+
super(payload.message);
|
|
9
|
+
this.payload = payload;
|
|
10
|
+
this.name = "IpcCallError";
|
|
11
|
+
}
|
|
12
|
+
payload;
|
|
13
|
+
get code() {
|
|
14
|
+
return this.payload.code;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
function createBridge(ipcRenderer) {
|
|
18
|
+
const listeners = /* @__PURE__ */ new Map();
|
|
19
|
+
ipcRenderer.on(CHANNELS.event, (_e, msg) => {
|
|
20
|
+
if (!msg || typeof msg.channel !== "string") return;
|
|
21
|
+
for (const l of [...listeners.get(msg.channel) ?? []]) {
|
|
22
|
+
try {
|
|
23
|
+
l(msg.payload);
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
async invoke(channel, input, caller) {
|
|
30
|
+
const req = { channel: String(channel), input, caller };
|
|
31
|
+
const res = await ipcRenderer.invoke(CHANNELS.invoke, req);
|
|
32
|
+
if (!res.ok) throw new IpcCallError(res.error);
|
|
33
|
+
return res.value;
|
|
34
|
+
},
|
|
35
|
+
send(channel, payload, caller) {
|
|
36
|
+
ipcRenderer.send(CHANNELS.send, { channel: String(channel), payload, caller });
|
|
37
|
+
},
|
|
38
|
+
on(channel, listener) {
|
|
39
|
+
let set = listeners.get(channel);
|
|
40
|
+
if (!set) listeners.set(channel, set = /* @__PURE__ */ new Set());
|
|
41
|
+
set.add(listener);
|
|
42
|
+
return () => void set.delete(listener);
|
|
43
|
+
},
|
|
44
|
+
bootstrap: () => ipcRenderer.invoke(CHANNELS.bootstrap)
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function exposeFluxBridge(contextBridge, ipcRenderer, key = "__fluxplugin") {
|
|
48
|
+
const bridge = createBridge(ipcRenderer);
|
|
49
|
+
contextBridge.exposeInMainWorld(key, bridge);
|
|
50
|
+
return bridge;
|
|
51
|
+
}
|
|
52
|
+
export {
|
|
53
|
+
IpcCallError,
|
|
54
|
+
createBridge,
|
|
55
|
+
exposeFluxBridge
|
|
56
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type BuildOptions } from "esbuild";
|
|
2
|
+
/** Convention: dist/X is built from src/X (main.ts, renderer.tsx, styles/*.css). */
|
|
3
|
+
export declare function buildOptions(root: string): Promise<BuildOptions[]>;
|
|
4
|
+
export declare function buildPlugin(root: string, watch?: boolean, log?: {
|
|
5
|
+
(...data: any[]): void;
|
|
6
|
+
(message?: any, ...optionalParams: any[]): void;
|
|
7
|
+
}): Promise<() => Promise<void>>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface CliConfig {
|
|
2
|
+
pluginsDir: string;
|
|
3
|
+
dataDir: string;
|
|
4
|
+
}
|
|
5
|
+
/** Resolves `--dir/--data` flags, then `fluxplugin.config.json` in the cwd, then defaults. */
|
|
6
|
+
export declare function loadConfig(flags: {
|
|
7
|
+
dir?: string;
|
|
8
|
+
data?: string;
|
|
9
|
+
}, cwd?: string): Promise<CliConfig>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export interface HostVars {
|
|
2
|
+
name: string;
|
|
3
|
+
fluxSpec: string;
|
|
4
|
+
}
|
|
5
|
+
/** Files of a new host application (`fluxplugin init`). Plain strings so the CLI stays a single self-contained file. */
|
|
6
|
+
export declare function hostFiles(v: HostVars, withSample?: boolean): Record<string, string>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type ChildProcess } from "node:child_process";
|
|
2
|
+
export declare function isHostProject(cwd: string): Promise<boolean>;
|
|
3
|
+
/** Bundles the host (renderer, main, preload, web) and every plugin in `pluginsDir`. */
|
|
4
|
+
export declare function buildHost(cwd: string, opts?: {
|
|
5
|
+
watch?: boolean;
|
|
6
|
+
log?: (m: string) => void;
|
|
7
|
+
}): Promise<() => Promise<void>>;
|
|
8
|
+
/** Starts the app: Electron when available (unless `web`), otherwise browser mode. Resolves when it exits. */
|
|
9
|
+
export declare function startApp(cwd: string, opts?: {
|
|
10
|
+
web?: boolean;
|
|
11
|
+
dev?: boolean;
|
|
12
|
+
port?: number;
|
|
13
|
+
}): {
|
|
14
|
+
child: ChildProcess;
|
|
15
|
+
mode: "electron" | "web";
|
|
16
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { run } from "./cli.js";
|
|
2
|
+
export { buildPlugin } from "./build.js";
|
|
3
|
+
export * from "./templates.js";
|
|
4
|
+
export { sharedModulesPlugin, SHARED_MODULES } from "./shared-modules.js";
|
|
5
|
+
export { buildHost, startApp, isHostProject } from "./host.js";
|
|
6
|
+
export { hostFiles } from "./host-templates.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Plugin } from "esbuild";
|
|
2
|
+
/** Modules provided by the host at runtime through `globalThis.__FLUXPLUGIN_SHARED__` (single instance of React, the runtime...). */
|
|
3
|
+
export declare const SHARED_MODULES: string[];
|
|
4
|
+
/**
|
|
5
|
+
* esbuild plugin rewriting imports of shared modules to `globalThis.__FLUXPLUGIN_SHARED__[id]`.
|
|
6
|
+
* Without it each plugin bundle would ship its own React and hooks would break (two React copies).
|
|
7
|
+
*/
|
|
8
|
+
export declare function sharedModulesPlugin(shared?: string[]): Plugin;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type TemplateName = "basic" | "dashboard" | "backend";
|
|
2
|
+
export interface TemplateVars {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
/** Short identifier usable as JS identifier / IPC prefix. */
|
|
6
|
+
slug: string;
|
|
7
|
+
Pascal: string;
|
|
8
|
+
}
|
|
9
|
+
export declare const TEMPLATES: Record<TemplateName, (v: TemplateVars) => Record<string, string>>;
|
|
10
|
+
export declare function varsFromName(name: string): TemplateVars;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PluginApis } from "./ipc.js";
|
|
2
|
+
/**
|
|
3
|
+
* Typed access to `window.plugins.<namespace>` in renderer code. Augment `PluginApis` to describe the API:
|
|
4
|
+
*
|
|
5
|
+
* ```ts
|
|
6
|
+
* declare module "fluxplugin" { interface PluginApis { analytics: { getStats(): Promise<Stats> } } }
|
|
7
|
+
* const stats = await pluginApi("analytics").getStats();
|
|
8
|
+
* ```
|
|
9
|
+
*/
|
|
10
|
+
export declare function pluginApi<K extends keyof PluginApis & string>(namespace: K): PluginApis[K];
|
|
11
|
+
export declare function hasPluginApi(namespace: string): boolean;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface Disposable {
|
|
2
|
+
dispose(): void;
|
|
3
|
+
}
|
|
4
|
+
export declare const toDisposable: (fn: () => void) => Disposable;
|
|
5
|
+
/** Collects disposables so that everything a plugin registered is removed when the plugin deactivates. */
|
|
6
|
+
export declare class DisposableStore implements Disposable {
|
|
7
|
+
private items;
|
|
8
|
+
private disposed;
|
|
9
|
+
add<T extends Disposable>(d: T): T;
|
|
10
|
+
get size(): number;
|
|
11
|
+
dispose(): void;
|
|
12
|
+
/** Re-arms the store so it can be reused after a deactivate/activate cycle. */
|
|
13
|
+
reset(): void;
|
|
14
|
+
}
|
|
15
|
+
export declare class FrameworkError extends Error {
|
|
16
|
+
readonly code: string;
|
|
17
|
+
readonly pluginId?: string | undefined;
|
|
18
|
+
constructor(message: string, code: string, pluginId?: string | undefined, options?: {
|
|
19
|
+
cause?: unknown;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export declare class PermissionDeniedError extends FrameworkError {
|
|
23
|
+
readonly permission: string;
|
|
24
|
+
constructor(pluginId: string, permission: string, api: string);
|
|
25
|
+
}
|
|
26
|
+
export declare class LifecycleError extends FrameworkError {
|
|
27
|
+
readonly phase: string;
|
|
28
|
+
constructor(pluginId: string, phase: string, message: string, cause?: unknown);
|
|
29
|
+
}
|
|
30
|
+
export declare class TimeoutError extends FrameworkError {
|
|
31
|
+
constructor(what: string, ms: number, pluginId?: string);
|
|
32
|
+
}
|
|
33
|
+
export declare class HookCancelledError extends FrameworkError {
|
|
34
|
+
readonly operation: string;
|
|
35
|
+
readonly reason?: string | undefined;
|
|
36
|
+
constructor(operation: string, reason?: string | undefined);
|
|
37
|
+
}
|
|
38
|
+
export declare function withTimeout<T>(p: Promise<T> | T, ms: number, what: string, pluginId?: string): Promise<T>;
|
|
39
|
+
export type LogLevel = "debug" | "info" | "warn" | "error";
|
|
40
|
+
export interface LogEntry {
|
|
41
|
+
level: LogLevel;
|
|
42
|
+
source: string;
|
|
43
|
+
message: string;
|
|
44
|
+
time: number;
|
|
45
|
+
data?: unknown;
|
|
46
|
+
}
|
|
47
|
+
export interface Logger {
|
|
48
|
+
debug(message: string, data?: unknown): void;
|
|
49
|
+
info(message: string, data?: unknown): void;
|
|
50
|
+
warn(message: string, data?: unknown): void;
|
|
51
|
+
error(message: string, data?: unknown): void;
|
|
52
|
+
}
|
|
53
|
+
/** In-memory ring buffer of log entries, queryable per plugin (used for diagnostics in the manager UI). */
|
|
54
|
+
export declare class LogStore {
|
|
55
|
+
private readonly capacity;
|
|
56
|
+
private readonly sink?;
|
|
57
|
+
private entries;
|
|
58
|
+
private listeners;
|
|
59
|
+
constructor(capacity?: number, sink?: ((e: LogEntry) => void) | undefined);
|
|
60
|
+
write(entry: LogEntry): void;
|
|
61
|
+
logger(source: string): Logger;
|
|
62
|
+
query(filter?: {
|
|
63
|
+
source?: string;
|
|
64
|
+
level?: LogLevel;
|
|
65
|
+
}): LogEntry[];
|
|
66
|
+
subscribe(l: (e: LogEntry) => void): Disposable;
|
|
67
|
+
clear(source?: string): void;
|
|
68
|
+
}
|
|
69
|
+
export declare function errorMessage(e: unknown): string;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { PluginManifest } from "./manifest.js";
|
|
2
|
+
export type DependencyIssue = {
|
|
3
|
+
type: "missing";
|
|
4
|
+
plugin: string;
|
|
5
|
+
dependency: string;
|
|
6
|
+
range: string;
|
|
7
|
+
kind: "dependencies" | "peerDependencies";
|
|
8
|
+
} | {
|
|
9
|
+
type: "version";
|
|
10
|
+
plugin: string;
|
|
11
|
+
dependency: string;
|
|
12
|
+
range: string;
|
|
13
|
+
found: string;
|
|
14
|
+
} | {
|
|
15
|
+
type: "cycle";
|
|
16
|
+
plugin: string;
|
|
17
|
+
path: string[];
|
|
18
|
+
};
|
|
19
|
+
export interface DependencyGraph {
|
|
20
|
+
manifests: Map<string, PluginManifest>;
|
|
21
|
+
/** Hard edges (dependencies + peerDependencies) plus optional ones that are installed. */
|
|
22
|
+
edges: Map<string, string[]>;
|
|
23
|
+
issues: DependencyIssue[];
|
|
24
|
+
/** Plugins that cannot be activated because of an issue (own or inherited from a dependency). */
|
|
25
|
+
blocked: Set<string>;
|
|
26
|
+
/** Global topological order (dependencies first) of every non-blocked plugin. */
|
|
27
|
+
order: string[];
|
|
28
|
+
}
|
|
29
|
+
export declare function buildDependencyGraph(manifests: Iterable<PluginManifest>): DependencyGraph;
|
|
30
|
+
/** `id` preceded by all of its transitive dependencies, dependencies first. */
|
|
31
|
+
export declare function activationOrderFor(graph: DependencyGraph, id: string): string[];
|
|
32
|
+
/** Plugins that (transitively) require `id`, ordered so that each one comes before what it depends on (safe deactivation order). */
|
|
33
|
+
export declare function dependentsOf(graph: DependencyGraph, id: string): string[];
|
|
34
|
+
export declare function describeIssue(i: DependencyIssue): string;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type Disposable } from "./common.js";
|
|
2
|
+
export interface EventContext<P = unknown> {
|
|
3
|
+
/** Concrete event name that was emitted (never a pattern). */
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly payload: P;
|
|
6
|
+
/** Plugin / component that emitted the event, when known. */
|
|
7
|
+
readonly source?: string;
|
|
8
|
+
readonly cancelled: boolean;
|
|
9
|
+
/** Stops propagation to lower-priority listeners and flags the emission as cancelled. */
|
|
10
|
+
cancel(): void;
|
|
11
|
+
}
|
|
12
|
+
export type EventListener<P = unknown> = (payload: P, ctx: EventContext<P>) => void | Promise<void>;
|
|
13
|
+
export interface ListenerOptions {
|
|
14
|
+
/** Higher runs first. Default 0. */
|
|
15
|
+
priority?: number;
|
|
16
|
+
once?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface EmitResult {
|
|
19
|
+
cancelled: boolean;
|
|
20
|
+
errors: unknown[];
|
|
21
|
+
delivered: number;
|
|
22
|
+
}
|
|
23
|
+
export declare function matchesPattern(pattern: string, name: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Typed event bus. `M` maps event names to payload types:
|
|
26
|
+
*
|
|
27
|
+
* ```ts
|
|
28
|
+
* const bus = new EventBus<{ "user.created": { id: string } }>();
|
|
29
|
+
* bus.on("user.created", (u) => u.id);
|
|
30
|
+
* bus.on("user.*", (payload, ctx) => ctx.name);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class EventBus<M extends Record<string, any> = Record<string, any>> {
|
|
34
|
+
private readonly onError;
|
|
35
|
+
private entries;
|
|
36
|
+
private seq;
|
|
37
|
+
constructor(onError?: (error: unknown, eventName: string, pattern: string) => void);
|
|
38
|
+
on<K extends keyof M & string>(name: K, listener: EventListener<M[K]>, opts?: ListenerOptions): Disposable;
|
|
39
|
+
on(pattern: string, listener: EventListener<any>, opts?: ListenerOptions): Disposable;
|
|
40
|
+
once<K extends keyof M & string>(name: K, listener: EventListener<M[K]>, opts?: Omit<ListenerOptions, "once">): Disposable;
|
|
41
|
+
once(pattern: string, listener: EventListener<any>, opts?: Omit<ListenerOptions, "once">): Disposable;
|
|
42
|
+
off(pattern: string, listener: EventListener<any>): void;
|
|
43
|
+
listenerCount(pattern?: string): number;
|
|
44
|
+
removeAll(): void;
|
|
45
|
+
private matching;
|
|
46
|
+
/** Synchronous emit. Async listeners are started but not awaited (their rejections go to `onError`). */
|
|
47
|
+
emit<K extends keyof M & string>(name: K, payload: M[K], source?: string): EmitResult;
|
|
48
|
+
emit(name: string, payload?: unknown, source?: string): EmitResult;
|
|
49
|
+
/** Awaits every listener sequentially (priority order). */
|
|
50
|
+
emitAsync<K extends keyof M & string>(name: K, payload: M[K], source?: string): Promise<EmitResult>;
|
|
51
|
+
emitAsync(name: string, payload?: unknown, source?: string): Promise<EmitResult>;
|
|
52
|
+
/** Resolves with the payload of the next matching event. */
|
|
53
|
+
waitFor<K extends keyof M & string>(name: K, timeoutMs?: number): Promise<M[K]>;
|
|
54
|
+
waitFor(pattern: string, timeoutMs?: number): Promise<unknown>;
|
|
55
|
+
private removeEntry;
|
|
56
|
+
private fail;
|
|
57
|
+
private makeCtx;
|
|
58
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { type Disposable } from "./common.js";
|
|
2
|
+
export type HookKind = "before" | "after" | "around" | "transform" | "validate" | "filter";
|
|
3
|
+
export interface HookContext<I = any, R = any> {
|
|
4
|
+
/** Operation name without the kind prefix, e.g. `user.create`. */
|
|
5
|
+
readonly operation: string;
|
|
6
|
+
/** Mutable input: `before` hooks may replace or edit it. */
|
|
7
|
+
input: I;
|
|
8
|
+
/** Result of the operation (available to `transform` and `after` hooks). */
|
|
9
|
+
result: R | undefined;
|
|
10
|
+
readonly cancelled: boolean;
|
|
11
|
+
readonly cancelReason: string | undefined;
|
|
12
|
+
/** Aborts the operation; `run()` rejects with `HookCancelledError`. */
|
|
13
|
+
cancel(reason?: string): void;
|
|
14
|
+
/** Shared scratch space between hooks of one run. */
|
|
15
|
+
readonly data: Map<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
export type AroundNext<R> = () => Promise<R>;
|
|
18
|
+
export type HookHandler<I = any, R = any> = ((ctx: HookContext<I, R>) => void | Promise<void>) | ((ctx: HookContext<I, R>) => R | Promise<R> | void | Promise<void>) | ((ctx: HookContext<I, R>, next: AroundNext<R>) => Promise<R> | R) | ((value: any, extra?: any) => any);
|
|
19
|
+
export interface HookOptions {
|
|
20
|
+
priority?: number;
|
|
21
|
+
owner?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Hook pipeline. Hosts wrap their operations with `run()`; plugins attach behaviours with `use()`.
|
|
25
|
+
*
|
|
26
|
+
* Execution order of `run("user.create", input, exec)`:
|
|
27
|
+
* validate → before → around (onion) → exec → transform → after
|
|
28
|
+
*
|
|
29
|
+
* `before`/`validate` may mutate `ctx.input`, call `ctx.cancel()` or throw to block the operation.
|
|
30
|
+
* `transform` may replace the result by returning a value. `after` is observational: errors are swallowed
|
|
31
|
+
* (reported through `onError`) so they cannot corrupt an operation that already succeeded.
|
|
32
|
+
*/
|
|
33
|
+
export declare class HookSystem {
|
|
34
|
+
private readonly onError;
|
|
35
|
+
private entries;
|
|
36
|
+
private seq;
|
|
37
|
+
constructor(onError?: (error: unknown, hookName: string, owner?: string) => void);
|
|
38
|
+
use<I = any, R = any>(name: `before.${string}` | `after.${string}` | `validate.${string}` | `transform.${string}`, handler: (ctx: HookContext<I, R>) => any, opts?: HookOptions): Disposable;
|
|
39
|
+
use<I = any, R = any>(name: `around.${string}`, handler: (ctx: HookContext<I, R>, next: AroundNext<R>) => any, opts?: HookOptions): Disposable;
|
|
40
|
+
use<V = any, X = any>(name: `filter.${string}`, handler: (value: V, extra?: X) => V | Promise<V>, opts?: HookOptions): Disposable;
|
|
41
|
+
count(kind?: HookKind, operation?: string): number;
|
|
42
|
+
list(): {
|
|
43
|
+
kind: HookKind;
|
|
44
|
+
operation: string;
|
|
45
|
+
priority: number;
|
|
46
|
+
owner?: string;
|
|
47
|
+
}[];
|
|
48
|
+
private get;
|
|
49
|
+
run<I, R>(operation: string, input: I, exec: (input: I, ctx: HookContext<I, R>) => R | Promise<R>): Promise<R>;
|
|
50
|
+
/** Runs `filter.<name>` handlers as a value pipeline. A failing filter is skipped and reported. */
|
|
51
|
+
filter<V, X = unknown>(name: string, value: V, extra?: X): Promise<V>;
|
|
52
|
+
/** Synchronous variant for render-time filters (async filters are ignored with a reported error). */
|
|
53
|
+
filterSync<V, X = unknown>(name: string, value: V, extra?: X): V;
|
|
54
|
+
removeByOwner(owner: string): void;
|
|
55
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export * from "./common.js";
|
|
2
|
+
export * from "./schema.js";
|
|
3
|
+
export * from "./semver.js";
|
|
4
|
+
export * from "./manifest.js";
|
|
5
|
+
export * from "./events.js";
|
|
6
|
+
export * from "./hooks.js";
|
|
7
|
+
export * from "./permissions.js";
|
|
8
|
+
export * from "./registry.js";
|
|
9
|
+
export * from "./routes.js";
|
|
10
|
+
export * from "./slots.js";
|
|
11
|
+
export * from "./styles.js";
|
|
12
|
+
export * from "./ipc.js";
|
|
13
|
+
export * from "./storage.js";
|
|
14
|
+
export * from "./deps.js";
|
|
15
|
+
export * from "./plugin.js";
|
|
16
|
+
export * from "./manager.js";
|
|
17
|
+
export * from "./protocol.js";
|
|
18
|
+
export * from "./api.js";
|