every-plugin 0.3.1 → 0.4.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/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/plugin.d.ts +27 -31
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +8 -5
- package/dist/runtime/index.d.ts +8 -20
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +63 -52
- package/dist/runtime/services/module-federation.service.d.ts.map +1 -1
- package/dist/runtime/services/module-federation.service.js +24 -3
- package/dist/runtime/services/plugin-loader.service.d.ts +11 -8
- package/dist/runtime/services/plugin-loader.service.d.ts.map +1 -1
- package/dist/runtime/services/plugin-loader.service.js +18 -15
- package/dist/runtime/services/plugin.service.d.ts +10 -7
- package/dist/runtime/services/plugin.service.d.ts.map +1 -1
- package/dist/testing/index.d.ts +15 -9
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/types.d.ts +100 -71
- package/dist/types.d.ts.map +1 -1
- package/package.json +103 -103
- package/dist/client/index.d.ts +0 -17
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js +0 -33
package/dist/index.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ export * from "./errors";
|
|
|
2
2
|
export * from "./plugin";
|
|
3
3
|
export * from "./runtime";
|
|
4
4
|
export { getNormalizedRemoteName } from "./runtime/services/normalize";
|
|
5
|
-
export type { AnyPlugin,
|
|
5
|
+
export type { AnyPlugin, EveryPlugin, InitializedPlugin, LoadedPlugin, PluginClientType, PluginConfigInput, PluginContext, PluginContract, PluginInstance, PluginMetadata, PluginRegistry, PluginRouterType, PluginRuntimeConfig, PluginSecrets, PluginVariables, RegisteredPlugins, SecretsConfig } from "./types";
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAG1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,YAAY,EACX,SAAS,EACT,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAG1B,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,YAAY,EACX,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,gBAAgB,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAClF,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,mBAAmB,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EACtE,aAAa,EACb,MAAM,SAAS,CAAC"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -1,37 +1,34 @@
|
|
|
1
|
-
import type { AnyContractRouter } from "@orpc/contract";
|
|
1
|
+
import type { AnyContractRouter, AnySchema, InferSchemaOutput } from "@orpc/contract";
|
|
2
2
|
import type { Context, Implementer, Router } from "@orpc/server";
|
|
3
3
|
import { Effect, type Scope } from "effect";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
/**
|
|
6
6
|
* Helper type that correctly constructs the config schema type
|
|
7
7
|
*/
|
|
8
|
-
export type PluginConfigFor<V extends
|
|
8
|
+
export type PluginConfigFor<V extends AnySchema, S extends AnySchema> = {
|
|
9
9
|
variables: V;
|
|
10
10
|
secrets: S;
|
|
11
|
-
}
|
|
11
|
+
};
|
|
12
12
|
/**
|
|
13
13
|
* Loaded plugin with static binding property
|
|
14
14
|
*/
|
|
15
|
-
export interface LoadedPluginWithBinding<TContract extends AnyContractRouter, TVariables extends
|
|
15
|
+
export interface LoadedPluginWithBinding<TContract extends AnyContractRouter, TVariables extends AnySchema, TSecrets extends AnySchema, TContext extends Context = Record<never, never>> {
|
|
16
16
|
new (): Plugin<TContract, TVariables, TSecrets, TContext>;
|
|
17
17
|
binding: {
|
|
18
18
|
contract: TContract;
|
|
19
|
+
variables: TVariables;
|
|
20
|
+
secrets: TSecrets;
|
|
19
21
|
config: PluginConfigFor<TVariables, TSecrets>;
|
|
22
|
+
context: TContext;
|
|
20
23
|
};
|
|
21
24
|
}
|
|
22
|
-
/**
|
|
23
|
-
* Utility type to extract binding from plugin constructor
|
|
24
|
-
*/
|
|
25
|
-
export type PluginBinding<T> = T extends {
|
|
26
|
-
binding: infer B;
|
|
27
|
-
} ? B : never;
|
|
28
25
|
/**
|
|
29
26
|
* Common error schemas that all plugins can use
|
|
30
27
|
* These provide consistent error handling across the plugin ecosystem
|
|
31
28
|
*/
|
|
32
29
|
export declare const CommonPluginErrors: {
|
|
33
|
-
UNAUTHORIZED: {
|
|
34
|
-
data: z.ZodObject<{
|
|
30
|
+
readonly UNAUTHORIZED: {
|
|
31
|
+
readonly data: z.ZodObject<{
|
|
35
32
|
apiKeyProvided: z.ZodBoolean;
|
|
36
33
|
provider: z.ZodOptional<z.ZodString>;
|
|
37
34
|
authType: z.ZodOptional<z.ZodEnum<{
|
|
@@ -41,8 +38,8 @@ export declare const CommonPluginErrors: {
|
|
|
41
38
|
}>>;
|
|
42
39
|
}, z.core.$strip>;
|
|
43
40
|
};
|
|
44
|
-
RATE_LIMITED: {
|
|
45
|
-
data: z.ZodObject<{
|
|
41
|
+
readonly RATE_LIMITED: {
|
|
42
|
+
readonly data: z.ZodObject<{
|
|
46
43
|
retryAfter: z.ZodNumber;
|
|
47
44
|
remainingRequests: z.ZodOptional<z.ZodNumber>;
|
|
48
45
|
resetTime: z.ZodOptional<z.ZodString>;
|
|
@@ -53,15 +50,15 @@ export declare const CommonPluginErrors: {
|
|
|
53
50
|
}>>;
|
|
54
51
|
}, z.core.$strip>;
|
|
55
52
|
};
|
|
56
|
-
SERVICE_UNAVAILABLE: {
|
|
57
|
-
data: z.ZodObject<{
|
|
53
|
+
readonly SERVICE_UNAVAILABLE: {
|
|
54
|
+
readonly data: z.ZodObject<{
|
|
58
55
|
retryAfter: z.ZodOptional<z.ZodNumber>;
|
|
59
56
|
maintenanceWindow: z.ZodDefault<z.ZodBoolean>;
|
|
60
57
|
estimatedUptime: z.ZodOptional<z.ZodString>;
|
|
61
58
|
}, z.core.$strip>;
|
|
62
59
|
};
|
|
63
|
-
BAD_REQUEST: {
|
|
64
|
-
data: z.ZodObject<{
|
|
60
|
+
readonly BAD_REQUEST: {
|
|
61
|
+
readonly data: z.ZodObject<{
|
|
65
62
|
invalidFields: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
66
63
|
validationErrors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
67
64
|
field: z.ZodString;
|
|
@@ -70,14 +67,14 @@ export declare const CommonPluginErrors: {
|
|
|
70
67
|
}, z.core.$strip>>>;
|
|
71
68
|
}, z.core.$strip>;
|
|
72
69
|
};
|
|
73
|
-
NOT_FOUND: {
|
|
74
|
-
data: z.ZodObject<{
|
|
70
|
+
readonly NOT_FOUND: {
|
|
71
|
+
readonly data: z.ZodObject<{
|
|
75
72
|
resource: z.ZodOptional<z.ZodString>;
|
|
76
73
|
resourceId: z.ZodOptional<z.ZodString>;
|
|
77
74
|
}, z.core.$strip>;
|
|
78
75
|
};
|
|
79
|
-
FORBIDDEN: {
|
|
80
|
-
data: z.ZodObject<{
|
|
76
|
+
readonly FORBIDDEN: {
|
|
77
|
+
readonly data: z.ZodObject<{
|
|
81
78
|
requiredPermissions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
82
79
|
action: z.ZodOptional<z.ZodString>;
|
|
83
80
|
}, z.core.$strip>;
|
|
@@ -86,34 +83,33 @@ export declare const CommonPluginErrors: {
|
|
|
86
83
|
/**
|
|
87
84
|
* Plugin interface
|
|
88
85
|
*/
|
|
89
|
-
export interface Plugin<TContract extends AnyContractRouter, TVariables extends
|
|
86
|
+
export interface Plugin<TContract extends AnyContractRouter, TVariables extends AnySchema, TSecrets extends AnySchema, TContext extends Context = Record<never, never>> {
|
|
90
87
|
readonly id: string;
|
|
91
88
|
readonly contract: TContract;
|
|
92
89
|
readonly configSchema: PluginConfigFor<TVariables, TSecrets>;
|
|
93
90
|
initialize(config: {
|
|
94
|
-
variables:
|
|
95
|
-
secrets:
|
|
91
|
+
variables: InferSchemaOutput<TVariables>;
|
|
92
|
+
secrets: InferSchemaOutput<TSecrets>;
|
|
96
93
|
}): Effect.Effect<TContext, unknown, Scope.Scope>;
|
|
97
94
|
shutdown(): Effect.Effect<void, never>;
|
|
98
95
|
/**
|
|
99
96
|
* Creates the strongly-typed oRPC router for this plugin.
|
|
100
97
|
* The router's procedure types are inferred directly from the contract.
|
|
101
98
|
* @param context The initialized plugin context
|
|
102
|
-
* @returns A router with procedures matching the plugin's contract
|
|
99
|
+
* @returns A router with procedures matching the plugin's contract
|
|
103
100
|
*/
|
|
104
|
-
createRouter
|
|
101
|
+
createRouter(context: TContext): Router<TContract, TContext>;
|
|
105
102
|
}
|
|
106
103
|
/**
|
|
107
104
|
* Factory function to create plugins
|
|
108
105
|
*/
|
|
109
|
-
export declare function createPlugin<V extends
|
|
110
|
-
id: string;
|
|
106
|
+
export declare function createPlugin<V extends AnySchema, S extends AnySchema, TContract extends AnyContractRouter, TContext extends Context = Record<never, never>>(config: {
|
|
111
107
|
variables: V;
|
|
112
108
|
secrets: S;
|
|
113
109
|
contract: TContract;
|
|
114
110
|
initialize?: (config: {
|
|
115
|
-
variables:
|
|
116
|
-
secrets:
|
|
111
|
+
variables: InferSchemaOutput<V>;
|
|
112
|
+
secrets: InferSchemaOutput<S>;
|
|
117
113
|
}) => Effect.Effect<TContext, Error, Scope.Scope>;
|
|
118
114
|
createRouter: (context: TContext, builder: Implementer<TContract, TContext & Record<never, never>, TContext & Record<never, never>>) => Router<TContract, TContext & Record<never, never>>;
|
|
119
115
|
shutdown?: (ctx: TContext) => Effect.Effect<void, Error, never>;
|
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,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.js
CHANGED
|
@@ -55,12 +55,13 @@ export const CommonPluginErrors = {
|
|
|
55
55
|
* Factory function to create plugins
|
|
56
56
|
*/
|
|
57
57
|
export function createPlugin(config) {
|
|
58
|
-
const configSchema =
|
|
58
|
+
const configSchema = {
|
|
59
59
|
variables: config.variables,
|
|
60
60
|
secrets: config.secrets
|
|
61
|
-
}
|
|
61
|
+
};
|
|
62
62
|
class CreatedPlugin {
|
|
63
|
-
|
|
63
|
+
/** set during instantiation - registry key */
|
|
64
|
+
id;
|
|
64
65
|
contract = config.contract;
|
|
65
66
|
configSchema = configSchema;
|
|
66
67
|
_context = null;
|
|
@@ -80,13 +81,15 @@ export function createPlugin(config) {
|
|
|
80
81
|
const builder = implement(config.contract).$context();
|
|
81
82
|
const router = config.createRouter(context, builder);
|
|
82
83
|
return router;
|
|
83
|
-
// return router as Router<TContract, TContext & THostContext>;
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
const PluginConstructor = CreatedPlugin;
|
|
87
87
|
PluginConstructor.binding = {
|
|
88
88
|
contract: config.contract,
|
|
89
|
-
|
|
89
|
+
variables: config.variables,
|
|
90
|
+
secrets: config.secrets,
|
|
91
|
+
config: configSchema,
|
|
92
|
+
context: {}
|
|
90
93
|
};
|
|
91
94
|
return PluginConstructor;
|
|
92
95
|
}
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { ManagedRuntime } from "effect";
|
|
2
|
-
import type {
|
|
3
|
-
import type { ConfigOf, EveryPlugin, InitializedPlugin, LoadedPlugin, PluginInstance, PluginOf, PluginRegistry, RegistryBindings, RuntimeOptions, SecretsConfig } from "../types";
|
|
2
|
+
import type { AnyPlugin, InitializedPlugin, LoadedPlugin, PluginConfigInput, PluginInstance, PluginRegistry, PluginRuntimeConfig, RegisteredPlugin, RegisteredPlugins, UsePluginResult } from "../types";
|
|
4
3
|
import { PluginService } from "./services/plugin.service";
|
|
5
|
-
export declare class PluginRuntime<R extends
|
|
4
|
+
export declare class PluginRuntime<R extends RegisteredPlugins = RegisteredPlugins> {
|
|
6
5
|
private runtime;
|
|
7
6
|
private registry;
|
|
8
7
|
private pluginCache;
|
|
@@ -10,23 +9,12 @@ export declare class PluginRuntime<R extends RegistryBindings = RegistryBindings
|
|
|
10
9
|
private generateCacheKey;
|
|
11
10
|
private validatePluginId;
|
|
12
11
|
private runPromise;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}>;
|
|
18
|
-
usePlugin<K extends keyof R>(pluginId: K, config: z.input<PluginOf<R[K]>["configSchema"]>): Promise<EveryPlugin<PluginOf<R[K]>> & {
|
|
19
|
-
initialized: InitializedPlugin<PluginOf<R[K]>> & {
|
|
20
|
-
config: ConfigOf<R[K]>;
|
|
21
|
-
};
|
|
22
|
-
}>;
|
|
12
|
+
usePlugin<K extends keyof RegisteredPlugins & string>(pluginId: K, config: PluginConfigInput<R[K]>): Promise<UsePluginResult<K>>;
|
|
13
|
+
loadPlugin<K extends keyof RegisteredPlugins & string>(pluginId: K): Promise<LoadedPlugin<RegisteredPlugin<K>>>;
|
|
14
|
+
instantiatePlugin<K extends keyof RegisteredPlugins & string>(pluginId: K, loadedPlugin: LoadedPlugin<RegisteredPlugin<K>>): Promise<PluginInstance<RegisteredPlugin<K>>>;
|
|
15
|
+
initializePlugin<T extends AnyPlugin>(instance: PluginInstance<T>, config: any): Promise<InitializedPlugin<T>>;
|
|
23
16
|
shutdown(): Promise<void>;
|
|
24
|
-
evictPlugin<K extends keyof
|
|
17
|
+
evictPlugin<K extends keyof RegisteredPlugins & string>(pluginId: K, config: PluginConfigInput<RegisteredPlugins[K]>): Promise<void>;
|
|
25
18
|
}
|
|
26
|
-
export declare function createPluginRuntime
|
|
27
|
-
registry: PluginRegistry;
|
|
28
|
-
secrets?: SecretsConfig;
|
|
29
|
-
options?: RuntimeOptions;
|
|
30
|
-
}): PluginRuntime<R>;
|
|
31
|
-
export type { ConfigOf, EveryPlugin, InitializedPlugin, PluginOf, RegistryBindings } from "../types";
|
|
19
|
+
export declare function createPluginRuntime(config: PluginRuntimeConfig): PluginRuntime;
|
|
32
20
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AACA,OAAO,EAA6B,cAAc,EAAU,MAAM,QAAQ,CAAC;AAC3E,OAAO,KAAK,EACX,SAAS,EACT,iBAAiB,EACjB,YAAY,EAEZ,iBAAiB,EACjB,cAAc,EACd,cAAc,EAEd,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,qBAAa,aAAa,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB;IAIxE,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,QAAQ;IAJjB,OAAO,CAAC,WAAW,CAAsF;gBAGhG,OAAO,EAAE,cAAc,CAAC,cAAc,CAAC,aAAa,EAAE,KAAK,CAAC,EAC5D,QAAQ,EAAE,cAAc;IAGjC,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,gBAAgB;YAcV,UAAU;IAgBlB,SAAS,CAAC,CAAC,SAAS,MAAM,iBAAiB,GAAG,MAAM,EACzD,QAAQ,EAAE,CAAC,EACX,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAC7B,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IAiCxB,UAAU,CAAC,CAAC,SAAS,MAAM,iBAAiB,GAAG,MAAM,EAC1D,QAAQ,EAAE,CAAC,GACT,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAQvC,iBAAiB,CAAC,CAAC,SAAS,MAAM,iBAAiB,GAAG,MAAM,EACjE,QAAQ,EAAE,CAAC,EACX,YAAY,EAAE,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAC7C,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAQzC,gBAAgB,CAAC,CAAC,SAAS,SAAS,EACzC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,EAC3B,MAAM,EAAE,GAAG,GACT,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;IAQ1B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAQzB,WAAW,CAAC,CAAC,SAAS,MAAM,iBAAiB,GAAG,MAAM,EAC3D,QAAQ,EAAE,CAAC,EACX,MAAM,EAAE,iBAAiB,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC;CAwBhB;AAWD,wBAAgB,mBAAmB,CAClC,MAAM,EAAE,mBAAmB,GACzB,aAAa,CAkBf"}
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { createRouterClient } from "@orpc/server";
|
|
1
2
|
import { Cause, Effect, Exit, Hash, ManagedRuntime, Option } from "effect";
|
|
2
|
-
import { createPluginClient, getPluginRouter } from "../client/index";
|
|
3
3
|
import { PluginRuntimeError } from "./errors";
|
|
4
4
|
import { PluginService } from "./services/plugin.service";
|
|
5
5
|
export class PluginRuntime {
|
|
@@ -15,16 +15,15 @@ export class PluginRuntime {
|
|
|
15
15
|
return `${pluginId}:${configHash}`;
|
|
16
16
|
}
|
|
17
17
|
validatePluginId(pluginId) {
|
|
18
|
-
|
|
19
|
-
if (!(pluginIdStr in this.registry)) {
|
|
18
|
+
if (!(pluginId in this.registry)) {
|
|
20
19
|
return Effect.fail(new PluginRuntimeError({
|
|
21
|
-
pluginId:
|
|
20
|
+
pluginId: String(pluginId),
|
|
22
21
|
operation: "validate-plugin-id",
|
|
23
|
-
cause: new Error(`Plugin ID '${
|
|
22
|
+
cause: new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),
|
|
24
23
|
retryable: false,
|
|
25
24
|
}));
|
|
26
25
|
}
|
|
27
|
-
return Effect.succeed(
|
|
26
|
+
return Effect.succeed(String(pluginId));
|
|
28
27
|
}
|
|
29
28
|
async runPromise(effect) {
|
|
30
29
|
const exit = await this.runtime.runPromiseExit(effect);
|
|
@@ -37,34 +36,8 @@ export class PluginRuntime {
|
|
|
37
36
|
}
|
|
38
37
|
return exit.value;
|
|
39
38
|
}
|
|
40
|
-
loadPlugin(pluginId) {
|
|
41
|
-
const effect = Effect.gen(this, function* () {
|
|
42
|
-
const pluginService = yield* PluginService;
|
|
43
|
-
const validatedId = yield* this.validatePluginId(pluginId);
|
|
44
|
-
const result = yield* pluginService.loadPlugin(validatedId);
|
|
45
|
-
return result;
|
|
46
|
-
});
|
|
47
|
-
return this.runPromise(effect);
|
|
48
|
-
}
|
|
49
|
-
instantiatePlugin(pluginId, loadedPlugin) {
|
|
50
|
-
const effect = Effect.gen(this, function* () {
|
|
51
|
-
const pluginService = yield* PluginService;
|
|
52
|
-
const pluginIdStr = pluginId;
|
|
53
|
-
const result = yield* pluginService.instantiatePlugin(pluginIdStr, loadedPlugin);
|
|
54
|
-
return result;
|
|
55
|
-
});
|
|
56
|
-
return this.runPromise(effect);
|
|
57
|
-
}
|
|
58
|
-
initializePlugin(instance, config) {
|
|
59
|
-
const effect = Effect.gen(this, function* () {
|
|
60
|
-
const pluginService = yield* PluginService;
|
|
61
|
-
const result = yield* pluginService.initializePlugin(instance, config);
|
|
62
|
-
return result;
|
|
63
|
-
});
|
|
64
|
-
return this.runPromise(effect);
|
|
65
|
-
}
|
|
66
39
|
async usePlugin(pluginId, config) {
|
|
67
|
-
const cacheKey = this.generateCacheKey(
|
|
40
|
+
const cacheKey = this.generateCacheKey(pluginId, config);
|
|
68
41
|
let cachedPlugin = this.pluginCache.get(cacheKey);
|
|
69
42
|
if (!cachedPlugin) {
|
|
70
43
|
const operation = Effect.gen(this, function* () {
|
|
@@ -72,49 +45,87 @@ export class PluginRuntime {
|
|
|
72
45
|
const validatedId = yield* this.validatePluginId(pluginId);
|
|
73
46
|
// Load → Instantiate → Initialize
|
|
74
47
|
const ctor = yield* pluginService.loadPlugin(validatedId);
|
|
75
|
-
const instance = yield* pluginService.instantiatePlugin(
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
const client = createPluginClient(initialized);
|
|
79
|
-
const router = getPluginRouter(initialized);
|
|
80
|
-
return {
|
|
81
|
-
client,
|
|
82
|
-
router,
|
|
83
|
-
metadata: initialized.metadata,
|
|
84
|
-
initialized
|
|
85
|
-
};
|
|
48
|
+
const instance = yield* pluginService.instantiatePlugin(pluginId, ctor);
|
|
49
|
+
const initialized = yield* pluginService.initializePlugin(instance, config);
|
|
50
|
+
return initialized;
|
|
86
51
|
}).pipe(Effect.provide(this.runtime));
|
|
87
52
|
cachedPlugin = Effect.cached(operation).pipe(Effect.flatten);
|
|
88
53
|
this.pluginCache.set(cacheKey, cachedPlugin);
|
|
89
54
|
}
|
|
90
|
-
|
|
55
|
+
const initialized = await this.runPromise(cachedPlugin);
|
|
56
|
+
const router = initialized.plugin.createRouter(initialized.context);
|
|
57
|
+
const client = createRouterClient(router);
|
|
58
|
+
return {
|
|
59
|
+
router: router,
|
|
60
|
+
client: client,
|
|
61
|
+
metadata: initialized.metadata,
|
|
62
|
+
initialized: initialized
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
async loadPlugin(pluginId) {
|
|
66
|
+
const effect = Effect.gen(function* () {
|
|
67
|
+
const pluginService = yield* PluginService;
|
|
68
|
+
return yield* pluginService.loadPlugin(pluginId);
|
|
69
|
+
});
|
|
70
|
+
return this.runPromise(effect);
|
|
71
|
+
}
|
|
72
|
+
async instantiatePlugin(pluginId, loadedPlugin) {
|
|
73
|
+
const effect = Effect.gen(function* () {
|
|
74
|
+
const pluginService = yield* PluginService;
|
|
75
|
+
return yield* pluginService.instantiatePlugin(pluginId, loadedPlugin);
|
|
76
|
+
});
|
|
77
|
+
return this.runPromise(effect);
|
|
78
|
+
}
|
|
79
|
+
async initializePlugin(instance, config) {
|
|
80
|
+
const effect = Effect.gen(function* () {
|
|
81
|
+
const pluginService = yield* PluginService;
|
|
82
|
+
return yield* pluginService.initializePlugin(instance, config);
|
|
83
|
+
});
|
|
84
|
+
return this.runPromise(effect);
|
|
91
85
|
}
|
|
92
|
-
shutdown() {
|
|
86
|
+
async shutdown() {
|
|
93
87
|
const effect = Effect.gen(function* () {
|
|
94
88
|
const pluginService = yield* PluginService;
|
|
95
89
|
yield* pluginService.cleanup();
|
|
96
90
|
});
|
|
97
91
|
return this.runPromise(effect);
|
|
98
92
|
}
|
|
99
|
-
evictPlugin(pluginId, config) {
|
|
100
|
-
const cacheKey = this.generateCacheKey(
|
|
93
|
+
async evictPlugin(pluginId, config) {
|
|
94
|
+
const cacheKey = this.generateCacheKey(pluginId, config);
|
|
101
95
|
const effect = Effect.gen(this, function* () {
|
|
102
96
|
const pluginService = yield* PluginService;
|
|
103
97
|
const cachedPlugin = this.pluginCache.get(cacheKey);
|
|
104
98
|
if (cachedPlugin) {
|
|
105
99
|
this.pluginCache.delete(cacheKey);
|
|
106
100
|
const pluginResult = yield* cachedPlugin.pipe(Effect.catchAll(() => Effect.succeed(null)));
|
|
107
|
-
if (pluginResult
|
|
108
|
-
yield* pluginService.shutdownPlugin(pluginResult
|
|
101
|
+
if (pluginResult) {
|
|
102
|
+
yield* pluginService.shutdownPlugin(pluginResult).pipe(Effect.catchAll(() => Effect.void));
|
|
109
103
|
}
|
|
110
104
|
}
|
|
111
105
|
}).pipe(Effect.catchAll(() => Effect.void));
|
|
112
106
|
return this.runPromise(effect);
|
|
113
107
|
}
|
|
114
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Normalizes a remote URL to ensure it points to remoteEntry.js
|
|
111
|
+
* If the URL doesn't end with a file extension, appends /remoteEntry.js
|
|
112
|
+
*/
|
|
113
|
+
function normalizeRemoteUrl(url) {
|
|
114
|
+
if (url.endsWith('.js'))
|
|
115
|
+
return url; // Already a file
|
|
116
|
+
return `${url.endsWith('/') ? url.slice(0, -1) : url}/remoteEntry.js`;
|
|
117
|
+
}
|
|
115
118
|
export function createPluginRuntime(config) {
|
|
116
119
|
const secrets = config.secrets || {};
|
|
117
|
-
|
|
120
|
+
// Normalize all remote URLs in the registry
|
|
121
|
+
const normalizedRegistry = Object.fromEntries(Object.entries(config.registry).map(([pluginId, entry]) => [
|
|
122
|
+
pluginId,
|
|
123
|
+
{
|
|
124
|
+
...entry,
|
|
125
|
+
remoteUrl: normalizeRemoteUrl(entry.remoteUrl)
|
|
126
|
+
}
|
|
127
|
+
]));
|
|
128
|
+
const layer = PluginService.Live(normalizedRegistry, secrets);
|
|
118
129
|
const runtime = ManagedRuntime.make(layer);
|
|
119
|
-
return new PluginRuntime(runtime,
|
|
130
|
+
return new PluginRuntime(runtime, normalizedRegistry);
|
|
120
131
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"module-federation.service.d.ts","sourceRoot":"","sources":["../../../src/runtime/services/module-federation.service.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;;;mCAkFpB,MAAM,OAAO,MAAM;0CA2CZ,MAAM,OAAO,MAAM,6BAxH/B,SAAS;;;AAwElC,qBAAa,uBAAwB,SAAQ,
|
|
1
|
+
{"version":3,"file":"module-federation.service.d.ts","sourceRoot":"","sources":["../../../src/runtime/services/module-federation.service.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;;;mCAkFpB,MAAM,OAAO,MAAM;0CA2CZ,MAAM,OAAO,MAAM,6BAxH/B,SAAS;;;AAwElC,qBAAa,uBAAwB,SAAQ,4BAkH3C;CAAG"}
|
|
@@ -112,11 +112,32 @@ export class ModuleFederationService extends Effect.Service()("ModuleFederationS
|
|
|
112
112
|
if (!container) {
|
|
113
113
|
throw new Error(`No container returned for ${modulePath}`);
|
|
114
114
|
}
|
|
115
|
+
// Support multiple export patterns: direct function, default export, named exports
|
|
115
116
|
const Constructor = typeof container === "function"
|
|
116
|
-
? container
|
|
117
|
-
: container.default
|
|
117
|
+
? container // Direct function export
|
|
118
|
+
: container.default
|
|
119
|
+
? container.default // Default export
|
|
120
|
+
: Object.values(container).find(// Named export fallback
|
|
121
|
+
(exp) => typeof exp === "function" && exp.prototype?.constructor === exp);
|
|
118
122
|
if (!Constructor || typeof Constructor !== "function") {
|
|
119
|
-
|
|
123
|
+
const containerInfo = typeof container === "object"
|
|
124
|
+
? `Available exports: ${Object.keys(container).join(', ')}`
|
|
125
|
+
: `Container type: ${typeof container}`;
|
|
126
|
+
throw new Error(`No valid plugin constructor found for '${pluginId}'.\n` +
|
|
127
|
+
`Supported patterns:\n` +
|
|
128
|
+
` - export const YourPlugin = createPlugin({...})\n` +
|
|
129
|
+
` - export default createPlugin({...})\n` +
|
|
130
|
+
`${containerInfo}`);
|
|
131
|
+
}
|
|
132
|
+
// Validate it looks like a plugin constructor (has binding property)
|
|
133
|
+
if (!Constructor.binding) {
|
|
134
|
+
const containerInfo = typeof container === "object"
|
|
135
|
+
? `Found exports: ${Object.keys(container).join(', ')}`
|
|
136
|
+
: `Container type: ${typeof container}`;
|
|
137
|
+
throw new Error(`Invalid plugin constructor for '${pluginId}'. ` +
|
|
138
|
+
`The exported value must be created with createPlugin(). ` +
|
|
139
|
+
`Found a function but it's missing the required 'binding' property.\n` +
|
|
140
|
+
`${containerInfo}`);
|
|
120
141
|
}
|
|
121
142
|
console.log(`[MF] ✅ Loaded constructor for ${pluginId}`);
|
|
122
143
|
return Constructor;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { InferSchemaInput, InferSchemaOutput } from "@orpc/contract";
|
|
1
2
|
import { Context, Effect, Scope } from "effect";
|
|
2
|
-
import type { z } from "zod";
|
|
3
3
|
import type { AnyPlugin, LoadedPlugin, PluginInstance, PluginRegistry } from "../../types";
|
|
4
4
|
import { PluginRuntimeError } from "../errors";
|
|
5
5
|
import { ModuleFederationService } from "./module-federation.service";
|
|
@@ -9,7 +9,7 @@ export declare class PluginRegistryTag extends PluginRegistryTag_base {
|
|
|
9
9
|
}
|
|
10
10
|
declare const RegistryService_base: Effect.Service.Class<RegistryService, "RegistryService", {
|
|
11
11
|
readonly effect: Effect.Effect<{
|
|
12
|
-
get: (pluginId: string) => Effect.Effect<import("
|
|
12
|
+
get: (pluginId: string) => Effect.Effect<import("../..").PluginMetadata, PluginRuntimeError, never>;
|
|
13
13
|
}, never, PluginRegistryTag>;
|
|
14
14
|
}>;
|
|
15
15
|
export declare class RegistryService extends RegistryService_base {
|
|
@@ -18,19 +18,22 @@ declare const PluginLoaderService_base: Effect.Service.Class<PluginLoaderService
|
|
|
18
18
|
readonly effect: Effect.Effect<{
|
|
19
19
|
loadPlugin: (pluginId: string) => Effect.Effect<{
|
|
20
20
|
ctor: new () => AnyPlugin;
|
|
21
|
-
metadata: import("
|
|
21
|
+
metadata: import("../..").PluginMetadata;
|
|
22
22
|
}, PluginRuntimeError, never>;
|
|
23
23
|
instantiatePlugin: <T extends AnyPlugin>(pluginId: string, loadedPlugin: LoadedPlugin<T>) => Effect.Effect<{
|
|
24
24
|
plugin: T;
|
|
25
|
-
metadata: import("
|
|
25
|
+
metadata: import("../..").PluginMetadata;
|
|
26
26
|
}, PluginRuntimeError, never>;
|
|
27
27
|
initializePlugin: <T extends AnyPlugin>(pluginInstance: PluginInstance<T>, config: {
|
|
28
|
-
variables:
|
|
29
|
-
secrets:
|
|
28
|
+
variables: InferSchemaInput<T["configSchema"]["variables"]>;
|
|
29
|
+
secrets: InferSchemaInput<T["configSchema"]["secrets"]>;
|
|
30
30
|
}) => Effect.Effect<{
|
|
31
31
|
plugin: T;
|
|
32
|
-
metadata: import("
|
|
33
|
-
config:
|
|
32
|
+
metadata: import("../..").PluginMetadata;
|
|
33
|
+
config: {
|
|
34
|
+
variables: InferSchemaOutput<T["configSchema"]["variables"]>;
|
|
35
|
+
secrets: InferSchemaOutput<T["configSchema"]["secrets"]>;
|
|
36
|
+
};
|
|
34
37
|
context: any;
|
|
35
38
|
scope: Scope.CloseableScope;
|
|
36
39
|
}, PluginRuntimeError, never>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-loader.service.d.ts","sourceRoot":"","sources":["../../../src/runtime/services/plugin-loader.service.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"plugin-loader.service.d.ts","sourceRoot":"","sources":["../../../src/runtime/services/plugin-loader.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEhD,OAAO,KAAK,EACX,SAAS,EAET,YAAY,EACZ,cAAc,EACd,cAAc,EACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAwB,MAAM,WAAW,CAAC;AAErE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;;AAEnD,qBAAa,iBAAkB,SAAQ,sBAGpC;CAAI;;;wBAOY,MAAM;;;AALzB,qBAAa,eAAgB,SAAQ,oBAkBnC;CAAI;;;+BAgBoB,MAAM;;;;4BAyBT,CAAC,SAAS,SAAS,YAC5B,MAAM,gBACF,YAAY,CAAC,CAAC,CAAC;;;;2BAuBX,CAAC,SAAS,SAAS,kBACrB,cAAc,CAAC,CAAC,CAAC,UACzB;YAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;SAAE;;;;;;;;;;;;AAlEpI,qBAAa,mBAAoB,SAAQ,wBAoJvC;CACD"}
|
|
@@ -11,7 +11,7 @@ export class RegistryService extends Effect.Service()("RegistryService", {
|
|
|
11
11
|
return {
|
|
12
12
|
get: (pluginId) => Effect.fromNullable(registry[pluginId]).pipe(Effect.mapError(() => new PluginRuntimeError({
|
|
13
13
|
pluginId,
|
|
14
|
-
operation: "
|
|
14
|
+
operation: "validate-plugin-id",
|
|
15
15
|
cause: new Error(`Plugin ${pluginId} not found in registry`),
|
|
16
16
|
retryable: false,
|
|
17
17
|
}))),
|
|
@@ -42,15 +42,7 @@ export class PluginLoaderService extends Effect.Service()("PluginLoaderService",
|
|
|
42
42
|
}),
|
|
43
43
|
instantiatePlugin: (pluginId, loadedPlugin) => Effect.gen(function* () {
|
|
44
44
|
const instance = yield* Effect.try(() => new loadedPlugin.ctor()).pipe(Effect.mapError((error) => toPluginRuntimeError(error, pluginId, undefined, "instantiate-plugin", false)));
|
|
45
|
-
|
|
46
|
-
if (instance.id !== pluginId) {
|
|
47
|
-
return yield* Effect.fail(new PluginRuntimeError({
|
|
48
|
-
pluginId,
|
|
49
|
-
operation: "validate-plugin-id",
|
|
50
|
-
cause: new Error(`Plugin ID mismatch: expected ${pluginId}, got ${instance.id}`),
|
|
51
|
-
retryable: false,
|
|
52
|
-
}));
|
|
53
|
-
}
|
|
45
|
+
instance.id = pluginId;
|
|
54
46
|
return {
|
|
55
47
|
plugin: instance,
|
|
56
48
|
metadata: loadedPlugin.metadata,
|
|
@@ -59,14 +51,25 @@ export class PluginLoaderService extends Effect.Service()("PluginLoaderService",
|
|
|
59
51
|
initializePlugin: (pluginInstance, config) => Effect.gen(function* () {
|
|
60
52
|
const { plugin } = pluginInstance;
|
|
61
53
|
// Validate and hydrate config
|
|
62
|
-
const
|
|
54
|
+
const validatedVariables = yield* validate(plugin.configSchema.variables, config.variables, plugin.id, "config").pipe(Effect.mapError((validationError) => new PluginRuntimeError({
|
|
63
55
|
pluginId: plugin.id,
|
|
64
56
|
operation: "validate-config",
|
|
65
57
|
cause: validationError.zodError,
|
|
66
58
|
retryable: false,
|
|
67
59
|
})));
|
|
68
|
-
|
|
69
|
-
const
|
|
60
|
+
// Validate secrets
|
|
61
|
+
const validatedSecrets = yield* validate(plugin.configSchema.secrets, config.secrets, plugin.id, "config").pipe(Effect.mapError((validationError) => new PluginRuntimeError({
|
|
62
|
+
pluginId: plugin.id,
|
|
63
|
+
operation: "validate-secrets",
|
|
64
|
+
cause: validationError.zodError,
|
|
65
|
+
retryable: false,
|
|
66
|
+
})));
|
|
67
|
+
// Hydrate secrets in variables
|
|
68
|
+
const hydratedConfig = yield* secretsService.hydrateSecrets({
|
|
69
|
+
variables: validatedVariables,
|
|
70
|
+
secrets: validatedSecrets,
|
|
71
|
+
});
|
|
72
|
+
const _variables = yield* validate(plugin.configSchema.variables, hydratedConfig.variables, plugin.id, "config").pipe(Effect.mapError((validationError) => new PluginRuntimeError({
|
|
70
73
|
pluginId: plugin.id,
|
|
71
74
|
operation: "validate-hydrated-config",
|
|
72
75
|
cause: validationError.zodError,
|
|
@@ -75,11 +78,11 @@ export class PluginLoaderService extends Effect.Service()("PluginLoaderService",
|
|
|
75
78
|
// Create a long-lived scope for this plugin instance
|
|
76
79
|
const scope = yield* Scope.make();
|
|
77
80
|
// Initialize plugin within the scope
|
|
78
|
-
const context = yield* plugin.initialize(
|
|
81
|
+
const context = yield* plugin.initialize({ variables: _variables, secrets: hydratedConfig.secrets }).pipe(Effect.provideService(Scope.Scope, scope), Effect.mapError((error) => toPluginRuntimeError(error, plugin.id, undefined, "initialize-plugin", false)));
|
|
79
82
|
return {
|
|
80
83
|
plugin,
|
|
81
84
|
metadata: pluginInstance.metadata,
|
|
82
|
-
config:
|
|
85
|
+
config: { variables: _variables, secrets: hydratedConfig.secrets },
|
|
83
86
|
context,
|
|
84
87
|
scope,
|
|
85
88
|
};
|
|
@@ -6,25 +6,28 @@ declare const PluginService_base: Effect.Service.Class<PluginService, "PluginSer
|
|
|
6
6
|
readonly scoped: Effect.Effect<{
|
|
7
7
|
loadPlugin: (pluginId: string) => Effect.Effect<{
|
|
8
8
|
ctor: new () => AnyPlugin;
|
|
9
|
-
metadata: import("
|
|
9
|
+
metadata: import("../..").PluginMetadata;
|
|
10
10
|
}, import("../errors").PluginRuntimeError, never>;
|
|
11
11
|
instantiatePlugin: <T extends AnyPlugin>(pluginId: string, loadedPlugin: import("../..").LoadedPlugin<T>) => Effect.Effect<{
|
|
12
12
|
plugin: T;
|
|
13
|
-
metadata: import("
|
|
13
|
+
metadata: import("../..").PluginMetadata;
|
|
14
14
|
}, import("../errors").PluginRuntimeError, never>;
|
|
15
15
|
initializePlugin: <T extends AnyPlugin>(pluginInstance: import("../..").PluginInstance<T>, config: {
|
|
16
|
-
variables:
|
|
17
|
-
secrets:
|
|
16
|
+
variables: import("@orpc/contract").InferSchemaInput<T["configSchema"]["variables"]>;
|
|
17
|
+
secrets: import("@orpc/contract").InferSchemaInput<T["configSchema"]["secrets"]>;
|
|
18
18
|
}) => Effect.Effect<{
|
|
19
19
|
plugin: T;
|
|
20
|
-
metadata: import("
|
|
21
|
-
config:
|
|
20
|
+
metadata: import("../..").PluginMetadata;
|
|
21
|
+
config: {
|
|
22
|
+
variables: import("@orpc/contract").InferSchemaOutput<T["configSchema"]["variables"]>;
|
|
23
|
+
secrets: import("@orpc/contract").InferSchemaOutput<T["configSchema"]["secrets"]>;
|
|
24
|
+
};
|
|
22
25
|
context: any;
|
|
23
26
|
scope: Scope.CloseableScope;
|
|
24
27
|
}, import("../errors").PluginRuntimeError, never>;
|
|
25
28
|
shutdownPlugin: (plugin: InitializedPlugin<AnyPlugin>) => Effect.Effect<void, never, never>;
|
|
26
29
|
cleanup: () => Effect.Effect<void, never, never>;
|
|
27
|
-
}, never,
|
|
30
|
+
}, never, PluginLifecycleService | PluginLoaderService>;
|
|
28
31
|
}>;
|
|
29
32
|
export declare class PluginService extends PluginService_base {
|
|
30
33
|
static Live: (registry: PluginRegistry, secrets: SecretsConfig) => Layer.Layer<PluginService, never, never>;
|