every-plugin 0.0.4 → 0.0.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.
- package/README.md +256 -6
- package/dist/errors.d.ts +8 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -2
- package/dist/index.d.ts +6 -0
- package/dist/index.js +3 -3
- package/dist/plugin.d.ts +57 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +1 -1
- package/dist/runtime/errors.d.ts +41 -0
- package/dist/runtime/errors.d.ts.map +1 -0
- package/dist/runtime/errors.js +7 -0
- package/dist/runtime/index.d.ts +21 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +34 -0
- package/dist/runtime/runtime.d.ts +58 -0
- package/dist/runtime/runtime.d.ts.map +1 -0
- package/dist/runtime/runtime.js +75 -0
- package/dist/runtime/runtime.test.d.ts +2 -0
- package/dist/runtime/runtime.test.d.ts.map +1 -0
- package/dist/runtime/runtime.test.js +308 -0
- package/dist/runtime/services/module-federation.service.d.ts +17 -0
- package/dist/runtime/services/module-federation.service.d.ts.map +1 -0
- package/dist/runtime/services/module-federation.service.js +108 -0
- package/dist/runtime/services/plugin-cache.service.d.ts +18 -0
- package/dist/runtime/services/plugin-cache.service.d.ts.map +1 -0
- package/dist/runtime/services/plugin-cache.service.js +55 -0
- package/dist/runtime/services/plugin.service.d.ts +22 -0
- package/dist/runtime/services/plugin.service.d.ts.map +1 -0
- package/dist/runtime/services/plugin.service.js +130 -0
- package/dist/runtime/services/secrets.service.d.ts +17 -0
- package/dist/runtime/services/secrets.service.d.ts.map +1 -0
- package/dist/runtime/services/secrets.service.js +32 -0
- package/dist/runtime/services.d.ts +5 -0
- package/dist/runtime/services.d.ts.map +1 -0
- package/dist/runtime/services.js +4 -0
- package/dist/runtime/types.d.ts +40 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +1 -0
- package/dist/runtime/validation.d.ts +10 -0
- package/dist/runtime/validation.d.ts.map +1 -0
- package/dist/runtime/validation.js +13 -0
- package/dist/source.d.ts +7 -7
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +35 -19
- package/package.json +40 -23
package/README.md
CHANGED
|
@@ -1,15 +1,265 @@
|
|
|
1
|
-
#
|
|
1
|
+
# every-plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A modular plugin runtime & system built with [Effect.TS](https://effect.website/) for loading, initializing, and executing remote plugins via [Module Federation](https://module-federation.io/).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
|
-
|
|
8
|
+
npm install every-plugin
|
|
9
|
+
# or
|
|
10
|
+
bun add every-plugin
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### Basic Plugin Usage
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { Effect, ManagedRuntime } from "effect";
|
|
19
|
+
import { PluginRuntime } from "every-plugin/runtime";
|
|
20
|
+
|
|
21
|
+
// Create a managed runtime (do this once per application/worker)
|
|
22
|
+
const runtime = ManagedRuntime.make(PluginRuntime.Live({
|
|
23
|
+
registry: {
|
|
24
|
+
"@my-org/data-processor": {
|
|
25
|
+
version: "1.0.0",
|
|
26
|
+
remoteUrl: "https://cdn.example.com/plugins/data-processor@latest/remoteEntry.js",
|
|
27
|
+
description: "Processes data items",
|
|
28
|
+
type: "pipeline"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
secrets: {
|
|
32
|
+
API_KEY: "your-secret-key",
|
|
33
|
+
DATABASE_URL: "postgresql://..."
|
|
34
|
+
},
|
|
35
|
+
logger: customLogger // optional
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
// Use the runtime to execute plugins
|
|
39
|
+
const result = await runtime.runPromise(
|
|
40
|
+
Effect.gen(function* () {
|
|
41
|
+
const pluginRuntime = yield* PluginRuntime;
|
|
42
|
+
|
|
43
|
+
// Use and execute a plugin in one step
|
|
44
|
+
const plugin = yield* pluginRuntime.usePlugin("@my-org/data-processor", {
|
|
45
|
+
apiKey: "{{API_KEY}}", // Will be hydrated from secrets
|
|
46
|
+
batchSize: 100
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const output = yield* pluginRuntime.executePlugin(plugin, {
|
|
50
|
+
items: ["item1", "item2", "item3"]
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
return output;
|
|
54
|
+
})
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
console.log(result);
|
|
58
|
+
|
|
59
|
+
// Clean up when done
|
|
60
|
+
await runtime.dispose();
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Alternative: Convenience Factory Function
|
|
64
|
+
|
|
65
|
+
If you prefer a factory function, you can use the convenience wrapper:
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
import { createPluginRuntime, PluginRuntime } from "every-plugin/runtime";
|
|
69
|
+
|
|
70
|
+
// This is equivalent to ManagedRuntime.make(PluginRuntime.Live(config))
|
|
71
|
+
const runtime = createPluginRuntime({
|
|
72
|
+
registry: { /* ... */ },
|
|
73
|
+
secrets: { /* ... */ }
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const result = await runtime.runPromise(
|
|
77
|
+
Effect.gen(function* () {
|
|
78
|
+
const pluginRuntime = yield* PluginRuntime;
|
|
79
|
+
return yield* pluginRuntime.usePlugin(pluginId, config);
|
|
80
|
+
})
|
|
81
|
+
);
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Advanced Usage - Granular Control
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
import { Effect } from "effect";
|
|
88
|
+
import { PluginRuntime } from "every-plugin/runtime";
|
|
89
|
+
|
|
90
|
+
const processWithGranularControl = Effect.gen(function* () {
|
|
91
|
+
const pluginRuntime = yield* PluginRuntime;
|
|
92
|
+
|
|
93
|
+
// Step-by-step plugin lifecycle
|
|
94
|
+
const constructor = yield* pluginRuntime.loadPlugin("@my-org/data-processor");
|
|
95
|
+
const instance = yield* pluginRuntime.instantiatePlugin(constructor);
|
|
96
|
+
const initialized = yield* pluginRuntime.initializePlugin(instance, config);
|
|
97
|
+
const output = yield* pluginRuntime.executePlugin(initialized, input);
|
|
98
|
+
|
|
99
|
+
return output;
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
await runtime.runPromise(processWithGranularControl);
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Worker Integration
|
|
106
|
+
|
|
107
|
+
Perfect for BullMQ workers or similar job processing systems:
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
import { Job } from "bullmq";
|
|
111
|
+
import { Effect } from "effect";
|
|
112
|
+
import { createPluginRuntime, PluginRuntime } from "every-plugin/runtime";
|
|
113
|
+
|
|
114
|
+
// Initialize runtime once per worker
|
|
115
|
+
const runtime = createPluginRuntime({
|
|
116
|
+
registry: pluginRegistry,
|
|
117
|
+
secrets: await loadSecrets(),
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// Job processor
|
|
121
|
+
const processJob = (job: Job) =>
|
|
122
|
+
runtime.runPromise(
|
|
123
|
+
Effect.gen(function* () {
|
|
124
|
+
const pluginRuntime = yield* PluginRuntime;
|
|
125
|
+
const { pluginId, config, input } = job.data;
|
|
126
|
+
|
|
127
|
+
const plugin = yield* pluginRuntime.usePlugin(pluginId, config);
|
|
128
|
+
return yield* pluginRuntime.executePlugin(plugin, input);
|
|
129
|
+
})
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
// Worker setup
|
|
133
|
+
const worker = new Worker("my-queue", processJob);
|
|
134
|
+
|
|
135
|
+
// Cleanup on shutdown
|
|
136
|
+
process.on("SIGTERM", async () => {
|
|
137
|
+
await worker.close();
|
|
138
|
+
await runtime.dispose();
|
|
139
|
+
});
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### React/Next.js Integration
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import { createPluginRuntime, PluginRuntime } from "every-plugin/runtime";
|
|
146
|
+
import { Effect } from "effect";
|
|
147
|
+
|
|
148
|
+
// Create runtime at app level
|
|
149
|
+
const pluginRuntime = createPluginRuntime({
|
|
150
|
+
registry: clientSideRegistry,
|
|
151
|
+
secrets: {} // No secrets on client side
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// In a React component or API route
|
|
155
|
+
export async function executePlugin(pluginId: string, config: any, input: any) {
|
|
156
|
+
return pluginRuntime.runPromise(
|
|
157
|
+
Effect.gen(function* () {
|
|
158
|
+
const runtime = yield* PluginRuntime;
|
|
159
|
+
const plugin = yield* runtime.usePlugin(pluginId, config);
|
|
160
|
+
return yield* runtime.executePlugin(plugin, input);
|
|
161
|
+
})
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Cleanup in app teardown
|
|
166
|
+
export function cleanup() {
|
|
167
|
+
return pluginRuntime.dispose();
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Core Concepts
|
|
172
|
+
|
|
173
|
+
### Plugin Registry
|
|
174
|
+
|
|
175
|
+
The registry defines available plugins and their remote locations:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
type PluginRegistry = {
|
|
179
|
+
[pluginId: string]: {
|
|
180
|
+
version: string;
|
|
181
|
+
remoteUrl: string;
|
|
182
|
+
description?: string;
|
|
183
|
+
type?: string;
|
|
184
|
+
};
|
|
185
|
+
};
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Secret Hydration
|
|
189
|
+
|
|
190
|
+
Secrets are automatically hydrated using Mustache-style templating:
|
|
191
|
+
|
|
192
|
+
```typescript
|
|
193
|
+
const config = {
|
|
194
|
+
apiKey: "{{API_KEY}}", // Will be replaced with actual secret
|
|
195
|
+
endpoint: "https://api.example.com"
|
|
196
|
+
};
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Plugin Lifecycle
|
|
200
|
+
|
|
201
|
+
1. **Load**: Download and cache the remote plugin module
|
|
202
|
+
2. **Instantiate**: Create a new instance of the plugin class
|
|
203
|
+
3. **Initialize**: Configure the plugin with validated config and secrets
|
|
204
|
+
4. **Execute**: Run the plugin with validated input, return validated output
|
|
205
|
+
|
|
206
|
+
### Error Handling
|
|
207
|
+
|
|
208
|
+
All operations return Effect types with proper error handling:
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
const result = await runtime.runPromise(
|
|
212
|
+
Effect.gen(function* () {
|
|
213
|
+
const pluginRuntime = yield* PluginRuntime;
|
|
214
|
+
return yield* pluginRuntime.usePlugin(pluginId, config);
|
|
215
|
+
}).pipe(
|
|
216
|
+
Effect.catchAll((error) => {
|
|
217
|
+
console.error("Plugin execution failed:", error);
|
|
218
|
+
return Effect.succeed(null); // Fallback value
|
|
219
|
+
})
|
|
220
|
+
)
|
|
221
|
+
);
|
|
7
222
|
```
|
|
8
223
|
|
|
9
|
-
|
|
224
|
+
## API Reference
|
|
225
|
+
|
|
226
|
+
### `createPluginRuntime(config)`
|
|
227
|
+
|
|
228
|
+
Creates a managed runtime for plugin execution.
|
|
229
|
+
|
|
230
|
+
**Parameters:**
|
|
231
|
+
|
|
232
|
+
- `config.registry`: Plugin registry mapping
|
|
233
|
+
- `config.secrets`: Secret values for hydration (optional)
|
|
234
|
+
- `config.logger`: Custom logger implementation (optional)
|
|
235
|
+
|
|
236
|
+
**Returns:** `ManagedRuntime` instance
|
|
237
|
+
|
|
238
|
+
### `PluginRuntime`
|
|
239
|
+
|
|
240
|
+
Effect service tag for accessing the plugin runtime within Effect workflows.
|
|
241
|
+
|
|
242
|
+
### Plugin Runtime Methods
|
|
243
|
+
|
|
244
|
+
- `loadPlugin(pluginId)`: Load plugin constructor from registry
|
|
245
|
+
- `instantiatePlugin(constructor)`: Create plugin instance
|
|
246
|
+
- `initializePlugin(instance, config)`: Initialize with config and secrets
|
|
247
|
+
- `executePlugin(plugin, input)`: Execute plugin with input
|
|
248
|
+
- `usePlugin(pluginId, config)`: Load + instantiate + initialize in one step
|
|
249
|
+
|
|
250
|
+
## Development
|
|
10
251
|
|
|
11
252
|
```bash
|
|
12
|
-
|
|
253
|
+
# Install dependencies
|
|
254
|
+
bun install
|
|
255
|
+
|
|
256
|
+
# Build the package
|
|
257
|
+
bun run build
|
|
258
|
+
|
|
259
|
+
# Run tests
|
|
260
|
+
bun test
|
|
13
261
|
```
|
|
14
262
|
|
|
15
|
-
|
|
263
|
+
## License
|
|
264
|
+
|
|
265
|
+
MIT
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare class PluginExecutionError extends Error {
|
|
2
|
+
readonly retryable: boolean;
|
|
3
|
+
constructor(message: string, retryable?: boolean);
|
|
4
|
+
}
|
|
5
|
+
export declare class ConfigurationError extends PluginExecutionError {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=errors.d.ts.map
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AACA,qBAAa,oBAAqB,SAAQ,KAAK;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AACA,qBAAa,oBAAqB,SAAQ,KAAK;aAG7B,SAAS,EAAE,OAAO;gBADlC,OAAO,EAAE,MAAM,EACC,SAAS,GAAE,OAAc;CAK1C;AAED,qBAAa,kBAAmB,SAAQ,oBAAoB;gBAC/C,OAAO,EAAE,MAAM;CAI3B"}
|
package/dist/errors.js
CHANGED
|
@@ -4,12 +4,12 @@ export class PluginExecutionError extends Error {
|
|
|
4
4
|
constructor(message, retryable = true) {
|
|
5
5
|
super(message);
|
|
6
6
|
this.retryable = retryable;
|
|
7
|
-
this.name =
|
|
7
|
+
this.name = "PluginExecutionError";
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
export class ConfigurationError extends PluginExecutionError {
|
|
11
11
|
constructor(message) {
|
|
12
12
|
super(message, false); // Configuration errors are not retryable
|
|
13
|
-
this.name =
|
|
13
|
+
this.name = "ConfigurationError";
|
|
14
14
|
}
|
|
15
15
|
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
CHANGED
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Context, type Effect } from "effect";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { ConfigurationError, PluginExecutionError } from "./errors";
|
|
4
|
+
export declare const createOutputSchema: <T extends z.ZodTypeAny>(dataSchema: T) => z.ZodObject<{
|
|
5
|
+
success: z.ZodBoolean;
|
|
6
|
+
data: z.ZodOptional<T>;
|
|
7
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
8
|
+
message: z.ZodString;
|
|
9
|
+
details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
10
|
+
stack: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>>>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
export declare function createConfigSchema<V extends z.ZodTypeAny, S extends z.ZodTypeAny>(variablesSchema?: V, secretsSchema?: S): z.ZodObject<{
|
|
14
|
+
variables: z.ZodOptional<V>;
|
|
15
|
+
secrets: z.ZodOptional<S>;
|
|
16
|
+
}>;
|
|
17
|
+
export declare function createInputSchema<I extends z.ZodTypeAny>(inputSchema: I): I;
|
|
18
|
+
export declare const ErrorDetailsSchema: z.ZodObject<{
|
|
19
|
+
message: z.ZodString;
|
|
20
|
+
details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
21
|
+
stack: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
export type ErrorDetails = z.infer<typeof ErrorDetailsSchema>;
|
|
24
|
+
export type Config<V extends z.ZodTypeAny = z.ZodRecord<z.ZodString, z.ZodUnknown>, S extends z.ZodTypeAny = z.ZodRecord<z.ZodString, z.ZodUnknown>> = z.infer<ReturnType<typeof createConfigSchema<V, S>>>;
|
|
25
|
+
export type Input<I extends z.ZodTypeAny> = z.infer<ReturnType<typeof createInputSchema<I>>>;
|
|
26
|
+
export type Output<T extends z.ZodTypeAny> = z.infer<ReturnType<typeof createOutputSchema<T>>>;
|
|
27
|
+
export interface Plugin<TInputSchema extends z.ZodTypeAny, TOutputSchema extends z.ZodTypeAny, TConfigSchema extends z.ZodTypeAny> {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly type: PluginType;
|
|
30
|
+
readonly inputSchema: TInputSchema;
|
|
31
|
+
readonly outputSchema: TOutputSchema;
|
|
32
|
+
readonly configSchema: TConfigSchema;
|
|
33
|
+
initialize(config?: z.infer<TConfigSchema>): Effect.Effect<void, ConfigurationError, PluginLoggerTag>;
|
|
34
|
+
execute(input: z.infer<TInputSchema>): Effect.Effect<z.infer<TOutputSchema>, PluginExecutionError, PluginLoggerTag>;
|
|
35
|
+
shutdown(): Effect.Effect<void, never, PluginLoggerTag>;
|
|
36
|
+
}
|
|
37
|
+
export type PluginType = "transformer" | "distributor" | "source";
|
|
38
|
+
export interface PluginMetadata {
|
|
39
|
+
remoteUrl: string;
|
|
40
|
+
type?: PluginType;
|
|
41
|
+
version?: string;
|
|
42
|
+
description?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface PluginRegistry {
|
|
45
|
+
[pluginId: string]: PluginMetadata;
|
|
46
|
+
}
|
|
47
|
+
export interface PluginLogger {
|
|
48
|
+
readonly logInfo: (message: string, context?: unknown) => Effect.Effect<void>;
|
|
49
|
+
readonly logWarning: (message: string, context?: unknown) => Effect.Effect<void>;
|
|
50
|
+
readonly logError: (message: string, error?: unknown, context?: unknown) => Effect.Effect<void>;
|
|
51
|
+
readonly logDebug: (message: string, context?: unknown) => Effect.Effect<void>;
|
|
52
|
+
}
|
|
53
|
+
declare const PluginLoggerTag_base: Context.TagClass<PluginLoggerTag, "PluginLogger", PluginLogger>;
|
|
54
|
+
export declare class PluginLoggerTag extends PluginLoggerTag_base {
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=plugin.d.ts.map
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.js
CHANGED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
declare const PluginRuntimeError_base: new <A extends Record<string, any> = {}>(
|
|
3
|
+
args: import("effect/Types").Equals<A, {}> extends true
|
|
4
|
+
? void
|
|
5
|
+
: { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] },
|
|
6
|
+
) => import("effect/Cause").YieldableError & {
|
|
7
|
+
readonly _tag: "PluginRuntimeError";
|
|
8
|
+
} & Readonly<A>;
|
|
9
|
+
export declare class PluginRuntimeError extends PluginRuntimeError_base<{
|
|
10
|
+
readonly pluginId?: string;
|
|
11
|
+
readonly operation: string;
|
|
12
|
+
readonly cause?: Error;
|
|
13
|
+
readonly retryable: boolean;
|
|
14
|
+
}> {}
|
|
15
|
+
declare const ModuleFederationError_base: new <
|
|
16
|
+
A extends Record<string, any> = {},
|
|
17
|
+
>(
|
|
18
|
+
args: import("effect/Types").Equals<A, {}> extends true
|
|
19
|
+
? void
|
|
20
|
+
: { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] },
|
|
21
|
+
) => import("effect/Cause").YieldableError & {
|
|
22
|
+
readonly _tag: "ModuleFederationError";
|
|
23
|
+
} & Readonly<A>;
|
|
24
|
+
export declare class ModuleFederationError extends ModuleFederationError_base<{
|
|
25
|
+
readonly pluginId: string;
|
|
26
|
+
readonly remoteUrl: string;
|
|
27
|
+
readonly cause?: Error;
|
|
28
|
+
}> {}
|
|
29
|
+
declare const ValidationError_base: new <A extends Record<string, any> = {}>(
|
|
30
|
+
args: import("effect/Types").Equals<A, {}> extends true
|
|
31
|
+
? void
|
|
32
|
+
: { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] },
|
|
33
|
+
) => import("effect/Cause").YieldableError & {
|
|
34
|
+
readonly _tag: "ValidationError";
|
|
35
|
+
} & Readonly<A>;
|
|
36
|
+
export declare class ValidationError extends ValidationError_base<{
|
|
37
|
+
readonly pluginId: string;
|
|
38
|
+
readonly stage: "config" | "input" | "output";
|
|
39
|
+
readonly zodError: z.ZodError;
|
|
40
|
+
}> {}
|
|
41
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/runtime/errors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;;;;AAE7B,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,CAAC;CAAI;;;;AAEN,qBAAa,qBAAsB,SAAQ,2BAA0C;IACnF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB,CAAC;CAAI;;;;AAEN,qBAAa,eAAgB,SAAQ,qBAAoC;IACvE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC9C,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC;CAC/B,CAAC;CAAI"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Data } from "effect";
|
|
2
|
+
export class PluginRuntimeError extends Data.TaggedError("PluginRuntimeError") {
|
|
3
|
+
}
|
|
4
|
+
export class ModuleFederationError extends Data.TaggedError("ModuleFederationError") {
|
|
5
|
+
}
|
|
6
|
+
export class ValidationError extends Data.TaggedError("ValidationError") {
|
|
7
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Effect, Layer, ManagedRuntime } from "effect";
|
|
2
|
+
import type { z } from "zod";
|
|
3
|
+
import type { PluginRuntimeError } from "./errors";
|
|
4
|
+
import type { AnyPlugin, InitializedPlugin, PluginConstructor, PluginInstance, PluginRuntimeConfig } from "./types";
|
|
5
|
+
export interface IPluginRuntime {
|
|
6
|
+
readonly loadPlugin: (pluginId: string) => Effect.Effect<PluginConstructor, PluginRuntimeError>;
|
|
7
|
+
readonly instantiatePlugin: <T extends AnyPlugin>(ctor: PluginConstructor) => Effect.Effect<PluginInstance<T>, PluginRuntimeError>;
|
|
8
|
+
readonly initializePlugin: <T extends AnyPlugin>(instance: PluginInstance<T>, config: z.infer<T["configSchema"]>) => Effect.Effect<InitializedPlugin<T>, PluginRuntimeError>;
|
|
9
|
+
readonly executePlugin: <T extends AnyPlugin>(initializedPlugin: InitializedPlugin<T>, input: z.infer<T["inputSchema"]>) => Effect.Effect<z.infer<T["outputSchema"]>, PluginRuntimeError>;
|
|
10
|
+
readonly createPlugin: <T extends AnyPlugin>(pluginId: string, config: z.infer<T["configSchema"]>) => Effect.Effect<InitializedPlugin<T>, PluginRuntimeError>;
|
|
11
|
+
readonly shutdown: () => Effect.Effect<void, never>;
|
|
12
|
+
}
|
|
13
|
+
declare const PluginRuntime_base: import("effect/Context").TagClass<PluginRuntime, "PluginRuntime", IPluginRuntime> & Effect.Tag.Proxy<PluginRuntime, IPluginRuntime> & {
|
|
14
|
+
use: <X>(body: (_: IPluginRuntime) => X) => [X] extends [Effect.Effect<infer A, infer E, infer R>] ? Effect.Effect<A, E, PluginRuntime | R> : [X] extends [PromiseLike<infer A_1>] ? Effect.Effect<A_1, import("effect/Cause").UnknownException, PluginRuntime> : Effect.Effect<X, never, PluginRuntime>;
|
|
15
|
+
};
|
|
16
|
+
export declare class PluginRuntime extends PluginRuntime_base {
|
|
17
|
+
static Live: (config: PluginRuntimeConfig) => Layer.Layer<PluginRuntime, never, never>;
|
|
18
|
+
}
|
|
19
|
+
export declare const createPluginRuntime: (config: PluginRuntimeConfig) => ManagedRuntime.ManagedRuntime<PluginRuntime, never>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACvD,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAOnD,OAAO,KAAK,EACX,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,MAAM,SAAS,CAAC;AAuBjB,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,UAAU,EAAE,CACpB,QAAQ,EAAE,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;IAC1D,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CAAC,SAAS,SAAS,EAC/C,IAAI,EAAE,iBAAiB,KACnB,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAC1D,QAAQ,CAAC,gBAAgB,EAAE,CAAC,CAAC,SAAS,SAAS,EAC9C,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,EAC3B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,KAC9B,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAC7D,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC,SAAS,SAAS,EAC3C,iBAAiB,EAAE,iBAAiB,CAAC,CAAC,CAAC,EACvC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,KAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;IACnE,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,SAAS,SAAS,EAC1C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,KAC9B,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAC7D,QAAQ,CAAC,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;CACpD;;;;AAED,qBAAa,aAAc,SAAQ,kBAGhC;IACF,MAAM,CAAC,IAAI,GAAI,QAAQ,mBAAmB,8CA4CxC;CACF;AAED,eAAO,MAAM,mBAAmB,GAAI,QAAQ,mBAAmB,wDACf,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Effect, Layer, ManagedRuntime } from "effect";
|
|
2
|
+
import { PluginLoggerTag } from "../plugin";
|
|
3
|
+
import { ModuleFederationService, PluginCacheService, PluginService, SecretsService, } from "./services";
|
|
4
|
+
// Default logger implementation
|
|
5
|
+
const createDefaultLogger = () => ({
|
|
6
|
+
logInfo: (message, context) => Effect.logInfo(message).pipe(Effect.annotateLogs({ source: "plugin", context })),
|
|
7
|
+
logWarning: (message, context) => Effect.logWarning(message).pipe(Effect.annotateLogs({ source: "plugin", context })),
|
|
8
|
+
logError: (message, error, context) => Effect.logError(message, error).pipe(Effect.annotateLogs({ source: "plugin", error, context })),
|
|
9
|
+
logDebug: (message, context) => Effect.logDebug(message).pipe(Effect.annotateLogs({ source: "plugin", context })),
|
|
10
|
+
});
|
|
11
|
+
export class PluginRuntime extends Effect.Tag("PluginRuntime")() {
|
|
12
|
+
static Live = (config) => {
|
|
13
|
+
const secrets = config.secrets || {};
|
|
14
|
+
const logger = config.logger || createDefaultLogger();
|
|
15
|
+
return Layer.effect(PluginRuntime, Effect.gen(function* () {
|
|
16
|
+
const pluginService = yield* PluginService;
|
|
17
|
+
return {
|
|
18
|
+
loadPlugin: pluginService.loadPlugin,
|
|
19
|
+
instantiatePlugin: pluginService.instantiatePlugin,
|
|
20
|
+
initializePlugin: pluginService.initializePlugin,
|
|
21
|
+
executePlugin: pluginService.executePlugin,
|
|
22
|
+
createPlugin: (pluginId, config) => Effect.gen(function* () {
|
|
23
|
+
const ctor = yield* pluginService.loadPlugin(pluginId);
|
|
24
|
+
const instance = yield* pluginService.instantiatePlugin(ctor);
|
|
25
|
+
return yield* pluginService.initializePlugin(instance, config);
|
|
26
|
+
}),
|
|
27
|
+
shutdown: () => Effect.sync(() => {
|
|
28
|
+
// Cleanup handled by Layer disposal
|
|
29
|
+
}),
|
|
30
|
+
};
|
|
31
|
+
})).pipe(Layer.provide(PluginService.Live(config.registry, secrets).pipe(Layer.provide(Layer.mergeAll(ModuleFederationService.Live, PluginCacheService.Live.pipe(Layer.provide(ModuleFederationService.Live)), SecretsService.Live(secrets), Layer.succeed(PluginLoggerTag, logger))))));
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export const createPluginRuntime = (config) => ManagedRuntime.make(PluginRuntime.Live(config));
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Effect, Layer, ManagedRuntime } from "effect";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { PluginRuntimeError } from "./errors";
|
|
4
|
+
import type {
|
|
5
|
+
AnyPlugin,
|
|
6
|
+
InitializedPlugin,
|
|
7
|
+
PluginConstructor,
|
|
8
|
+
PluginInstance,
|
|
9
|
+
PluginRuntimeConfig,
|
|
10
|
+
} from "./types";
|
|
11
|
+
export interface IPluginRuntime {
|
|
12
|
+
readonly loadPlugin: (
|
|
13
|
+
pluginId: string,
|
|
14
|
+
) => Effect.Effect<PluginConstructor, PluginRuntimeError>;
|
|
15
|
+
readonly instantiatePlugin: <T extends AnyPlugin>(
|
|
16
|
+
ctor: PluginConstructor,
|
|
17
|
+
) => Effect.Effect<PluginInstance<T>, PluginRuntimeError>;
|
|
18
|
+
readonly initializePlugin: <T extends AnyPlugin>(
|
|
19
|
+
instance: PluginInstance<T>,
|
|
20
|
+
config: z.infer<T["configSchema"]>,
|
|
21
|
+
) => Effect.Effect<InitializedPlugin<T>, PluginRuntimeError>;
|
|
22
|
+
readonly executePlugin: <T extends AnyPlugin>(
|
|
23
|
+
initializedPlugin: InitializedPlugin<T>,
|
|
24
|
+
input: z.infer<T["inputSchema"]>,
|
|
25
|
+
) => Effect.Effect<z.infer<T["outputSchema"]>, PluginRuntimeError>;
|
|
26
|
+
readonly createPlugin: <T extends AnyPlugin>(
|
|
27
|
+
pluginId: string,
|
|
28
|
+
config: z.infer<T["configSchema"]>,
|
|
29
|
+
) => Effect.Effect<InitializedPlugin<T>, PluginRuntimeError>;
|
|
30
|
+
readonly shutdown: () => Effect.Effect<void, never>;
|
|
31
|
+
}
|
|
32
|
+
declare const PluginRuntime_base: import("effect/Context").TagClass<
|
|
33
|
+
PluginRuntime,
|
|
34
|
+
"PluginRuntime",
|
|
35
|
+
IPluginRuntime
|
|
36
|
+
> &
|
|
37
|
+
Effect.Tag.Proxy<PluginRuntime, IPluginRuntime> & {
|
|
38
|
+
use: <X>(
|
|
39
|
+
body: (_: IPluginRuntime) => X,
|
|
40
|
+
) => [X] extends [Effect.Effect<infer A, infer E, infer R>]
|
|
41
|
+
? Effect.Effect<A, E, R | PluginRuntime>
|
|
42
|
+
: [X] extends [PromiseLike<infer A_1>]
|
|
43
|
+
? Effect.Effect<
|
|
44
|
+
A_1,
|
|
45
|
+
import("effect/Cause").UnknownException,
|
|
46
|
+
PluginRuntime
|
|
47
|
+
>
|
|
48
|
+
: Effect.Effect<X, never, PluginRuntime>;
|
|
49
|
+
};
|
|
50
|
+
export declare class PluginRuntime extends PluginRuntime_base {
|
|
51
|
+
static Live: (
|
|
52
|
+
config: PluginRuntimeConfig,
|
|
53
|
+
) => Layer.Layer<PluginRuntime, never, never>;
|
|
54
|
+
}
|
|
55
|
+
export declare const createManagedPluginRuntime: (
|
|
56
|
+
config: PluginRuntimeConfig,
|
|
57
|
+
) => ManagedRuntime.ManagedRuntime<PluginRuntime, never>;
|
|
58
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACvD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAO9C,OAAO,KAAK,EACX,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EAEnB,MAAM,SAAS,CAAC;AAuBjB,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,UAAU,EAAE,CACpB,QAAQ,EAAE,MAAM,KACZ,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;IAC1D,QAAQ,CAAC,iBAAiB,EAAE,CAAC,CAAC,SAAS,SAAS,EAC/C,IAAI,EAAE,iBAAiB,KACnB,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAC1D,QAAQ,CAAC,gBAAgB,EAAE,CAAC,CAAC,SAAS,SAAS,EAC9C,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,EAC3B,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,KAC9B,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAC7D,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC,SAAS,SAAS,EAC3C,iBAAiB,EAAE,iBAAiB,CAAC,CAAC,CAAC,EACvC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,KAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;IACnE,QAAQ,CAAC,YAAY,EAAE,CAAC,CAAC,SAAS,SAAS,EAC1C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,KAC9B,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;IAC7D,QAAQ,CAAC,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;CACpD;;;;AAGD,qBAAa,aAAc,SAAQ,kBAGhC;IACF,MAAM,CAAC,IAAI,GAAI,QAAQ,mBAAmB,8CA4CxC;CACF;AAGD,eAAO,MAAM,0BAA0B,GAAI,QAAQ,mBAAmB,wDACtB,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Effect, Layer, ManagedRuntime } from "effect";
|
|
2
|
+
import { PluginLoggerTag } from "../plugin";
|
|
3
|
+
import {
|
|
4
|
+
ModuleFederationService,
|
|
5
|
+
PluginCacheService,
|
|
6
|
+
PluginService,
|
|
7
|
+
SecretsService,
|
|
8
|
+
} from "./services";
|
|
9
|
+
|
|
10
|
+
// Default logger implementation
|
|
11
|
+
const createDefaultLogger = () => ({
|
|
12
|
+
logInfo: (message, context) =>
|
|
13
|
+
Effect.logInfo(message).pipe(
|
|
14
|
+
Effect.annotateLogs({ source: "plugin", context }),
|
|
15
|
+
),
|
|
16
|
+
logWarning: (message, context) =>
|
|
17
|
+
Effect.logWarning(message).pipe(
|
|
18
|
+
Effect.annotateLogs({ source: "plugin", context }),
|
|
19
|
+
),
|
|
20
|
+
logError: (message, error, context) =>
|
|
21
|
+
Effect.logError(message, error).pipe(
|
|
22
|
+
Effect.annotateLogs({ source: "plugin", error, context }),
|
|
23
|
+
),
|
|
24
|
+
logDebug: (message, context) =>
|
|
25
|
+
Effect.logDebug(message).pipe(
|
|
26
|
+
Effect.annotateLogs({ source: "plugin", context }),
|
|
27
|
+
),
|
|
28
|
+
});
|
|
29
|
+
// Main PluginRuntime service using Effect.Tag pattern
|
|
30
|
+
export class PluginRuntime extends Effect.Tag("PluginRuntime")() {
|
|
31
|
+
static Live = (config) => {
|
|
32
|
+
const secrets = config.secrets || {};
|
|
33
|
+
const logger = config.logger || createDefaultLogger();
|
|
34
|
+
return Layer.effect(
|
|
35
|
+
PluginRuntime,
|
|
36
|
+
Effect.gen(function* () {
|
|
37
|
+
const pluginService = yield* PluginService;
|
|
38
|
+
return {
|
|
39
|
+
loadPlugin: pluginService.loadPlugin,
|
|
40
|
+
instantiatePlugin: pluginService.instantiatePlugin,
|
|
41
|
+
initializePlugin: pluginService.initializePlugin,
|
|
42
|
+
executePlugin: pluginService.executePlugin,
|
|
43
|
+
createPlugin: (pluginId, config) =>
|
|
44
|
+
Effect.gen(function* () {
|
|
45
|
+
const ctor = yield* pluginService.loadPlugin(pluginId);
|
|
46
|
+
const instance = yield* pluginService.instantiatePlugin(ctor);
|
|
47
|
+
return yield* pluginService.initializePlugin(instance, config);
|
|
48
|
+
}),
|
|
49
|
+
shutdown: () =>
|
|
50
|
+
Effect.sync(() => {
|
|
51
|
+
// Cleanup handled by Layer disposal
|
|
52
|
+
}),
|
|
53
|
+
};
|
|
54
|
+
}),
|
|
55
|
+
).pipe(
|
|
56
|
+
Layer.provide(
|
|
57
|
+
PluginService.Live(config.registry, secrets).pipe(
|
|
58
|
+
Layer.provide(
|
|
59
|
+
Layer.mergeAll(
|
|
60
|
+
ModuleFederationService.Live,
|
|
61
|
+
PluginCacheService.Live.pipe(
|
|
62
|
+
Layer.provide(ModuleFederationService.Live),
|
|
63
|
+
),
|
|
64
|
+
SecretsService.Live(secrets),
|
|
65
|
+
Layer.succeed(PluginLoggerTag, logger),
|
|
66
|
+
),
|
|
67
|
+
),
|
|
68
|
+
),
|
|
69
|
+
),
|
|
70
|
+
);
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
// ManagedRuntime factory function
|
|
74
|
+
export const createManagedPluginRuntime = (config) =>
|
|
75
|
+
ManagedRuntime.make(PluginRuntime.Live(config));
|