every-plugin 0.5.0 → 0.6.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/{chunk-QQAxy9l9.mjs → _virtual/rolldown_runtime.cjs} +3 -7
- package/dist/{chunk-zltIcp7o.cjs → _virtual/rolldown_runtime.mjs} +4 -28
- package/dist/build/rspack/dev-server-middleware.cjs +201 -0
- package/dist/build/rspack/dev-server-middleware.cjs.map +1 -0
- package/dist/build/rspack/dev-server-middleware.mjs +200 -0
- package/dist/build/rspack/dev-server-middleware.mjs.map +1 -0
- package/dist/build/rspack/index.cjs +2 -362
- package/dist/build/rspack/index.d.cts +2 -20
- package/dist/build/rspack/index.d.mts +2 -20
- package/dist/build/rspack/index.mjs +2 -360
- package/dist/build/rspack/module-federation.cjs +46 -0
- package/dist/build/rspack/module-federation.cjs.map +1 -0
- package/dist/build/rspack/module-federation.mjs +46 -0
- package/dist/build/rspack/module-federation.mjs.map +1 -0
- package/dist/build/rspack/plugin.cjs +90 -0
- package/dist/build/rspack/plugin.cjs.map +1 -0
- package/dist/build/rspack/plugin.d.cts +20 -0
- package/dist/build/rspack/plugin.d.cts.map +1 -0
- package/dist/build/rspack/plugin.d.mts +20 -0
- package/dist/build/rspack/plugin.d.mts.map +1 -0
- package/dist/build/rspack/plugin.mjs +89 -0
- package/dist/build/rspack/plugin.mjs.map +1 -0
- package/dist/build/rspack/utils.cjs +41 -0
- package/dist/build/rspack/utils.cjs.map +1 -0
- package/dist/build/rspack/utils.mjs +38 -0
- package/dist/build/rspack/utils.mjs.map +1 -0
- package/dist/errors.cjs +103 -3
- package/dist/errors.cjs.map +1 -0
- package/dist/errors.d.cts +103 -3
- package/dist/errors.d.cts.map +1 -0
- package/dist/errors.d.mts +103 -3
- package/dist/errors.d.mts.map +1 -0
- package/dist/errors.mjs +102 -3
- package/dist/errors.mjs.map +1 -0
- package/dist/index.cjs +9 -55
- package/dist/index.d.cts +6 -5
- package/dist/index.d.mts +6 -5
- package/dist/index.mjs +5 -51
- package/dist/orpc.cjs +1 -1
- package/dist/package.cjs +29 -0
- package/dist/package.cjs.map +1 -0
- package/dist/package.mjs +17 -0
- package/dist/package.mjs.map +1 -0
- package/dist/plugin.cjs +48 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +62 -0
- package/dist/plugin.d.cts.map +1 -0
- package/dist/plugin.d.mts +62 -0
- package/dist/plugin.d.mts.map +1 -0
- package/dist/plugin.mjs +47 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/runtime/errors.cjs +97 -0
- package/dist/runtime/errors.cjs.map +1 -0
- package/dist/runtime/errors.d.cts +27 -0
- package/dist/runtime/errors.d.cts.map +1 -0
- package/dist/runtime/errors.d.mts +27 -0
- package/dist/runtime/errors.d.mts.map +1 -0
- package/dist/runtime/errors.mjs +93 -0
- package/dist/runtime/errors.mjs.map +1 -0
- package/dist/runtime/index.cjs +157 -5
- package/dist/runtime/index.cjs.map +1 -0
- package/dist/runtime/index.d.cts +43 -5
- package/dist/runtime/index.d.cts.map +1 -0
- package/dist/runtime/index.d.mts +43 -5
- package/dist/runtime/index.d.mts.map +1 -0
- package/dist/runtime/index.mjs +155 -4
- package/dist/runtime/index.mjs.map +1 -0
- package/dist/runtime/services/module-federation.service.cjs +142 -0
- package/dist/runtime/services/module-federation.service.cjs.map +1 -0
- package/dist/runtime/services/module-federation.service.d.cts +15 -0
- package/dist/runtime/services/module-federation.service.d.cts.map +1 -0
- package/dist/runtime/services/module-federation.service.d.mts +15 -0
- package/dist/runtime/services/module-federation.service.d.mts.map +1 -0
- package/dist/runtime/services/module-federation.service.mjs +141 -0
- package/dist/runtime/services/module-federation.service.mjs.map +1 -0
- package/dist/runtime/services/normalize.cjs +22 -2
- package/dist/runtime/services/normalize.cjs.map +1 -0
- package/dist/runtime/services/normalize.d.cts +21 -2
- package/dist/runtime/services/normalize.d.cts.map +1 -0
- package/dist/runtime/services/normalize.d.mts +21 -2
- package/dist/runtime/services/normalize.d.mts.map +1 -0
- package/dist/runtime/services/normalize.mjs +21 -2
- package/dist/runtime/services/normalize.mjs.map +1 -0
- package/dist/runtime/services/plugin-lifecycle.service.cjs +33 -0
- package/dist/runtime/services/plugin-lifecycle.service.cjs.map +1 -0
- package/dist/runtime/services/plugin-lifecycle.service.d.cts +17 -0
- package/dist/runtime/services/plugin-lifecycle.service.d.cts.map +1 -0
- package/dist/runtime/services/plugin-lifecycle.service.d.mts +17 -0
- package/dist/runtime/services/plugin-lifecycle.service.d.mts.map +1 -0
- package/dist/runtime/services/plugin-lifecycle.service.mjs +32 -0
- package/dist/runtime/services/plugin-lifecycle.service.mjs.map +1 -0
- package/dist/runtime/services/plugin-loader.service.cjs +132 -0
- package/dist/runtime/services/plugin-loader.service.cjs.map +1 -0
- package/dist/runtime/services/plugin-loader.service.d.cts +54 -0
- package/dist/runtime/services/plugin-loader.service.d.cts.map +1 -0
- package/dist/runtime/services/plugin-loader.service.d.mts +54 -0
- package/dist/runtime/services/plugin-loader.service.d.mts.map +1 -0
- package/dist/runtime/services/plugin-loader.service.mjs +128 -0
- package/dist/runtime/services/plugin-loader.service.mjs.map +1 -0
- package/dist/runtime/services/plugin.service.cjs +33 -0
- package/dist/runtime/services/plugin.service.cjs.map +1 -0
- package/dist/runtime/services/plugin.service.d.cts +42 -0
- package/dist/runtime/services/plugin.service.d.cts.map +1 -0
- package/dist/runtime/services/plugin.service.d.mts +42 -0
- package/dist/runtime/services/plugin.service.d.mts.map +1 -0
- package/dist/runtime/services/plugin.service.mjs +32 -0
- package/dist/runtime/services/plugin.service.mjs.map +1 -0
- package/dist/runtime/services/secrets.service.cjs +50 -0
- package/dist/runtime/services/secrets.service.cjs.map +1 -0
- package/dist/runtime/services/secrets.service.d.cts +16 -0
- package/dist/runtime/services/secrets.service.d.cts.map +1 -0
- package/dist/runtime/services/secrets.service.d.mts +16 -0
- package/dist/runtime/services/secrets.service.d.mts.map +1 -0
- package/dist/runtime/services/secrets.service.mjs +48 -0
- package/dist/runtime/services/secrets.service.mjs.map +1 -0
- package/dist/runtime/validation.cjs +18 -0
- package/dist/runtime/validation.cjs.map +1 -0
- package/dist/runtime/validation.mjs +17 -0
- package/dist/runtime/validation.mjs.map +1 -0
- package/dist/testing/index.cjs +2 -4
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +4 -4
- package/dist/testing/index.d.mts +4 -4
- package/dist/testing/index.mjs +1 -3
- package/dist/testing/index.mjs.map +1 -1
- package/dist/types.cjs +0 -0
- package/dist/types.d.cts +261 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +261 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +1 -0
- package/dist/zod-core.cjs +9 -0
- package/dist/zod-core.d.cts +1 -0
- package/dist/zod-core.d.mts +1 -0
- package/dist/zod-core.mjs +3 -0
- package/dist/zod.cjs +13 -1
- package/dist/zod.cjs.map +1 -0
- package/dist/zod.d.cts +8 -2
- package/dist/zod.d.cts.map +1 -0
- package/dist/zod.d.mts +8 -2
- package/dist/zod.d.mts.map +1 -0
- package/dist/zod.mjs +9 -2
- package/dist/zod.mjs.map +1 -0
- package/package.json +17 -2
- package/dist/build/rspack/index.cjs.map +0 -1
- package/dist/build/rspack/index.d.cts.map +0 -1
- package/dist/build/rspack/index.d.mts.map +0 -1
- package/dist/build/rspack/index.mjs.map +0 -1
- package/dist/errors-9sNpYLv5.d.mts +0 -75
- package/dist/errors-9sNpYLv5.d.mts.map +0 -1
- package/dist/errors-CVnoPl9v.cjs +0 -68
- package/dist/errors-CVnoPl9v.cjs.map +0 -1
- package/dist/errors-D7keKf7a.mjs +0 -63
- package/dist/errors-D7keKf7a.mjs.map +0 -1
- package/dist/errors-DKPPPYYT.d.cts +0 -75
- package/dist/errors-DKPPPYYT.d.cts.map +0 -1
- package/dist/fetch-8DauUFDh.mjs +0 -335
- package/dist/fetch-8DauUFDh.mjs.map +0 -1
- package/dist/fetch-CrBvwsZ4.cjs +0 -336
- package/dist/fetch-CrBvwsZ4.cjs.map +0 -1
- package/dist/index-Bu2wtZrA.d.mts +0 -463
- package/dist/index-Bu2wtZrA.d.mts.map +0 -1
- package/dist/index-DtTqwV4f.d.cts +0 -462
- package/dist/index-DtTqwV4f.d.cts.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/normalize-BW7kk8Lk.d.cts +0 -21
- package/dist/normalize-BW7kk8Lk.d.cts.map +0 -1
- package/dist/normalize-D4Qh0wVk.cjs +0 -28
- package/dist/normalize-D4Qh0wVk.cjs.map +0 -1
- package/dist/normalize-D7nae0Hn.mjs +0 -22
- package/dist/normalize-D7nae0Hn.mjs.map +0 -1
- package/dist/normalize-eB_j86fm.d.mts +0 -21
- package/dist/normalize-eB_j86fm.d.mts.map +0 -1
- package/dist/package-CaRYwbRi.mjs +0 -150
- package/dist/package-CaRYwbRi.mjs.map +0 -1
- package/dist/package-DyTuSutr.cjs +0 -155
- package/dist/package-DyTuSutr.cjs.map +0 -1
- package/dist/plugins-C6MGKdD-.mjs +0 -790
- package/dist/plugins-C6MGKdD-.mjs.map +0 -1
- package/dist/plugins-DNaNtkG7.cjs +0 -791
- package/dist/plugins-DNaNtkG7.cjs.map +0 -1
- package/dist/runtime-BNcFgWDG.cjs +0 -558
- package/dist/runtime-BNcFgWDG.cjs.map +0 -1
- package/dist/runtime-CAWcnrAk.mjs +0 -547
- package/dist/runtime-CAWcnrAk.mjs.map +0 -1
- package/dist/standard-CkH8zNkx.mjs +0 -584
- package/dist/standard-CkH8zNkx.mjs.map +0 -1
- package/dist/standard-v75BC6Z5.cjs +0 -685
- package/dist/standard-v75BC6Z5.cjs.map +0 -1
- package/dist/zod-A7Pti5IV.d.cts +0 -4
- package/dist/zod-A7Pti5IV.d.cts.map +0 -1
- package/dist/zod-BVo51kgJ.mjs +0 -10
- package/dist/zod-BVo51kgJ.mjs.map +0 -1
- package/dist/zod-DYghWCz1.cjs +0 -14
- package/dist/zod-DYghWCz1.cjs.map +0 -1
- package/dist/zod-Zw8dlP3j.d.mts +0 -4
- package/dist/zod-Zw8dlP3j.d.mts.map +0 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import "zod";
|
|
2
|
+
import "@orpc/contract";
|
|
3
|
+
import * as effect_Types0 from "effect/Types";
|
|
4
|
+
import * as effect_Cause0 from "effect/Cause";
|
|
5
|
+
|
|
6
|
+
//#region src/runtime/errors.d.ts
|
|
7
|
+
declare const PluginRuntimeError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
|
|
8
|
+
readonly _tag: "PluginRuntimeError";
|
|
9
|
+
} & Readonly<A>;
|
|
10
|
+
declare class PluginRuntimeError extends PluginRuntimeError_base<{
|
|
11
|
+
readonly pluginId?: string;
|
|
12
|
+
readonly operation?: string;
|
|
13
|
+
readonly procedureName?: string;
|
|
14
|
+
readonly cause?: Error;
|
|
15
|
+
readonly retryable: boolean;
|
|
16
|
+
}> {}
|
|
17
|
+
declare const ModuleFederationError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
|
|
18
|
+
readonly _tag: "ModuleFederationError";
|
|
19
|
+
} & Readonly<A>;
|
|
20
|
+
declare class ModuleFederationError extends ModuleFederationError_base<{
|
|
21
|
+
readonly pluginId: string;
|
|
22
|
+
readonly remoteUrl: string;
|
|
23
|
+
readonly cause?: Error;
|
|
24
|
+
}> {}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { ModuleFederationError, PluginRuntimeError };
|
|
27
|
+
//# sourceMappingURL=errors.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.cts","names":[],"sources":["../../src/runtime/errors.ts"],"sourcesContent":[],"mappings":";;;;;;cAE6B;;;cAEhB,kBAAA,SAA2B;EAFX,SAAA,QAAA,CAAA,EAAA,MAAA;;;mBAMX;;;cAEZ;;;cAEO,qBAAA,SAA8B;;;EAR9B,SAAA,KAAA,CAAA,EAaK,KAbc;AAM1B,CAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ORPCError } from "@orpc/contract";
|
|
3
|
+
import * as effect_Types0 from "effect/Types";
|
|
4
|
+
import * as effect_Cause0 from "effect/Cause";
|
|
5
|
+
|
|
6
|
+
//#region src/runtime/errors.d.ts
|
|
7
|
+
declare const PluginRuntimeError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
|
|
8
|
+
readonly _tag: "PluginRuntimeError";
|
|
9
|
+
} & Readonly<A>;
|
|
10
|
+
declare class PluginRuntimeError extends PluginRuntimeError_base<{
|
|
11
|
+
readonly pluginId?: string;
|
|
12
|
+
readonly operation?: string;
|
|
13
|
+
readonly procedureName?: string;
|
|
14
|
+
readonly cause?: Error;
|
|
15
|
+
readonly retryable: boolean;
|
|
16
|
+
}> {}
|
|
17
|
+
declare const ModuleFederationError_base: new <A extends Record<string, any> = {}>(args: effect_Types0.Equals<A, {}> extends true ? void : { readonly [P in keyof A as P extends "_tag" ? never : P]: A[P] }) => effect_Cause0.YieldableError & {
|
|
18
|
+
readonly _tag: "ModuleFederationError";
|
|
19
|
+
} & Readonly<A>;
|
|
20
|
+
declare class ModuleFederationError extends ModuleFederationError_base<{
|
|
21
|
+
readonly pluginId: string;
|
|
22
|
+
readonly remoteUrl: string;
|
|
23
|
+
readonly cause?: Error;
|
|
24
|
+
}> {}
|
|
25
|
+
//#endregion
|
|
26
|
+
export { ModuleFederationError, PluginRuntimeError };
|
|
27
|
+
//# sourceMappingURL=errors.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.mts","names":[],"sources":["../../src/runtime/errors.ts"],"sourcesContent":[],"mappings":";;;;;;cAE6B;;;cAEhB,kBAAA,SAA2B;EAFX,SAAA,QAAA,CAAA,EAAA,MAAA;;;mBAMX;;;cAEZ;;;cAEO,qBAAA,SAA8B;;;EAR9B,SAAA,KAAA,CAAA,EAaK,KAbc;AAM1B,CAAA,CAAA,CAAA"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { Data } from "effect";
|
|
2
|
+
import { ORPCError } from "@orpc/contract";
|
|
3
|
+
|
|
4
|
+
//#region src/runtime/errors.ts
|
|
5
|
+
var PluginRuntimeError = class extends Data.TaggedError("PluginRuntimeError") {};
|
|
6
|
+
var ModuleFederationError = class extends Data.TaggedError("ModuleFederationError") {};
|
|
7
|
+
var ValidationError = class extends Data.TaggedError("ValidationError") {};
|
|
8
|
+
const extractErrorMessage = (error) => {
|
|
9
|
+
if (!error) return "Unknown error";
|
|
10
|
+
if (error instanceof Error) {
|
|
11
|
+
if (error.message) return error.message;
|
|
12
|
+
if (error.cause instanceof Error) return extractErrorMessage(error.cause);
|
|
13
|
+
}
|
|
14
|
+
if (error instanceof AggregateError && error.errors?.length) return error.errors.map((e) => extractErrorMessage(e)).join("; ");
|
|
15
|
+
if (typeof error === "object" && "message" in error) return String(error.message);
|
|
16
|
+
return String(error);
|
|
17
|
+
};
|
|
18
|
+
const formatPluginError = (pluginId, operation, message) => {
|
|
19
|
+
const lines = [];
|
|
20
|
+
lines.push(`\n╭─ Plugin Error ${"─".repeat(40)}`);
|
|
21
|
+
if (pluginId) lines.push(`│ Plugin: ${pluginId}`);
|
|
22
|
+
if (operation) lines.push(`│ During: ${operation}`);
|
|
23
|
+
lines.push(`│`);
|
|
24
|
+
if (message.includes("ECONNREFUSED")) {
|
|
25
|
+
lines.push(`│ ❌ Connection refused`);
|
|
26
|
+
lines.push(`│ `);
|
|
27
|
+
lines.push(`│ A required service is not running.`);
|
|
28
|
+
lines.push(`│ → Run: docker compose up -d`);
|
|
29
|
+
} else if (message.includes("ENOTFOUND")) {
|
|
30
|
+
lines.push(`│ ❌ Host not found`);
|
|
31
|
+
lines.push(`│ `);
|
|
32
|
+
lines.push(`│ Check your connection URL or network settings.`);
|
|
33
|
+
} else if (message.includes("ETIMEDOUT") || message.includes("timeout")) {
|
|
34
|
+
lines.push(`│ ❌ Connection timeout`);
|
|
35
|
+
lines.push(`│ `);
|
|
36
|
+
lines.push(`│ The service took too long to respond.`);
|
|
37
|
+
} else if (message.includes("EACCES") || message.includes("permission")) {
|
|
38
|
+
lines.push(`│ ❌ Permission denied`);
|
|
39
|
+
lines.push(`│ `);
|
|
40
|
+
lines.push(`│ Check credentials or access permissions.`);
|
|
41
|
+
} else if (message.includes("401") || message.includes("unauthorized")) {
|
|
42
|
+
lines.push(`│ ❌ Authentication failed`);
|
|
43
|
+
lines.push(`│ `);
|
|
44
|
+
lines.push(`│ Check your API key or credentials.`);
|
|
45
|
+
} else lines.push(`│ ❌ ${message}`);
|
|
46
|
+
lines.push(`╰${"─".repeat(50)}\n`);
|
|
47
|
+
console.error(lines.join("\n"));
|
|
48
|
+
};
|
|
49
|
+
const isRetryableError = (message) => {
|
|
50
|
+
return [
|
|
51
|
+
"ETIMEDOUT",
|
|
52
|
+
"ECONNRESET",
|
|
53
|
+
"timeout",
|
|
54
|
+
"503",
|
|
55
|
+
"429"
|
|
56
|
+
].some((p) => message.toLowerCase().includes(p.toLowerCase()));
|
|
57
|
+
};
|
|
58
|
+
const isRetryableORPCCode = (code) => {
|
|
59
|
+
switch (code) {
|
|
60
|
+
case "TOO_MANY_REQUESTS":
|
|
61
|
+
case "SERVICE_UNAVAILABLE":
|
|
62
|
+
case "BAD_GATEWAY":
|
|
63
|
+
case "GATEWAY_TIMEOUT":
|
|
64
|
+
case "TIMEOUT": return true;
|
|
65
|
+
default: return false;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const wrapORPCError = (orpcError, pluginId, procedureName, operation) => {
|
|
69
|
+
return new PluginRuntimeError({
|
|
70
|
+
pluginId,
|
|
71
|
+
operation,
|
|
72
|
+
procedureName,
|
|
73
|
+
retryable: isRetryableORPCCode(orpcError.code),
|
|
74
|
+
cause: orpcError
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
const toPluginRuntimeError = (error, pluginId, procedureName, operation, defaultRetryable = false) => {
|
|
78
|
+
if (error instanceof ORPCError) return wrapORPCError(error, pluginId, procedureName, operation);
|
|
79
|
+
if (error instanceof PluginRuntimeError) return error;
|
|
80
|
+
const message = extractErrorMessage(error);
|
|
81
|
+
formatPluginError(pluginId, operation, message);
|
|
82
|
+
return new PluginRuntimeError({
|
|
83
|
+
pluginId,
|
|
84
|
+
operation,
|
|
85
|
+
procedureName,
|
|
86
|
+
retryable: defaultRetryable || isRetryableError(message),
|
|
87
|
+
cause: error instanceof Error ? error : new Error(message)
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
//#endregion
|
|
92
|
+
export { ModuleFederationError, PluginRuntimeError, ValidationError, toPluginRuntimeError };
|
|
93
|
+
//# sourceMappingURL=errors.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.mjs","names":["lines: string[]"],"sources":["../../src/runtime/errors.ts"],"sourcesContent":["import { ORPCError } from \"@orpc/contract\";\nimport { Data } from \"effect\";\nimport type { z } from \"zod\";\n\nexport class PluginRuntimeError extends Data.TaggedError(\"PluginRuntimeError\")<{\n\treadonly pluginId?: string;\n\treadonly operation?: string;\n\treadonly procedureName?: string;\n\treadonly cause?: Error;\n\treadonly retryable: boolean;\n}> { }\n\nexport class ModuleFederationError extends Data.TaggedError(\n\t\"ModuleFederationError\",\n)<{\n\treadonly pluginId: string;\n\treadonly remoteUrl: string;\n\treadonly cause?: Error;\n}> { }\n\nexport class ValidationError extends Data.TaggedError(\"ValidationError\")<{\n\treadonly pluginId: string;\n\treadonly stage: \"config\" | \"input\" | \"output\" | \"state\";\n\treadonly zodError: z.ZodError;\n}> { }\n\nconst extractErrorMessage = (error: unknown): string => {\n\tif (!error) return 'Unknown error';\n\n\tif (error instanceof Error) {\n\t\tif (error.message) return error.message;\n\t\tif ((error as any).cause instanceof Error) {\n\t\t\treturn extractErrorMessage((error as any).cause);\n\t\t}\n\t}\n\n\tif (error instanceof AggregateError && error.errors?.length) {\n\t\treturn error.errors.map(e => extractErrorMessage(e)).join('; ');\n\t}\n\n\tif (typeof error === 'object' && 'message' in error) {\n\t\treturn String((error as any).message);\n\t}\n\n\treturn String(error);\n};\n\nconst formatPluginError = (\n\tpluginId: string | undefined,\n\toperation: string | undefined,\n\tmessage: string\n): void => {\n\tconst lines: string[] = [];\n\n\tlines.push(`\\n╭─ Plugin Error ${'─'.repeat(40)}`);\n\tif (pluginId) lines.push(`│ Plugin: ${pluginId}`);\n\tif (operation) lines.push(`│ During: ${operation}`);\n\tlines.push(`│`);\n\n\tif (message.includes('ECONNREFUSED')) {\n\t\tlines.push(`│ ❌ Connection refused`);\n\t\tlines.push(`│ `);\n\t\tlines.push(`│ A required service is not running.`);\n\t\tlines.push(`│ → Run: docker compose up -d`);\n\t} else if (message.includes('ENOTFOUND')) {\n\t\tlines.push(`│ ❌ Host not found`);\n\t\tlines.push(`│ `);\n\t\tlines.push(`│ Check your connection URL or network settings.`);\n\t} else if (message.includes('ETIMEDOUT') || message.includes('timeout')) {\n\t\tlines.push(`│ ❌ Connection timeout`);\n\t\tlines.push(`│ `);\n\t\tlines.push(`│ The service took too long to respond.`);\n\t} else if (message.includes('EACCES') || message.includes('permission')) {\n\t\tlines.push(`│ ❌ Permission denied`);\n\t\tlines.push(`│ `);\n\t\tlines.push(`│ Check credentials or access permissions.`);\n\t} else if (message.includes('401') || message.includes('unauthorized')) {\n\t\tlines.push(`│ ❌ Authentication failed`);\n\t\tlines.push(`│ `);\n\t\tlines.push(`│ Check your API key or credentials.`);\n\t} else {\n\t\tlines.push(`│ ❌ ${message}`);\n\t}\n\n\tlines.push(`╰${'─'.repeat(50)}\\n`);\n\n\tconsole.error(lines.join('\\n'));\n};\n\nconst isRetryableError = (message: string): boolean => {\n\tconst retryablePatterns = ['ETIMEDOUT', 'ECONNRESET', 'timeout', '503', '429'];\n\treturn retryablePatterns.some(p => message.toLowerCase().includes(p.toLowerCase()));\n};\n\n// Helper to determine if an oRPC error code is retryable\nexport const isRetryableORPCCode = (code: string): boolean => {\n\tswitch (code) {\n\t\tcase 'TOO_MANY_REQUESTS':\n\t\tcase 'SERVICE_UNAVAILABLE':\n\t\tcase 'BAD_GATEWAY':\n\t\tcase 'GATEWAY_TIMEOUT':\n\t\tcase 'TIMEOUT':\n\t\t\treturn true;\n\t\tdefault:\n\t\t\treturn false;\n\t}\n};\n\n// Convert ORPC errors from plugin procedures to PluginRuntimeError\nexport const wrapORPCError = (\n\torpcError: ORPCError<string, unknown>,\n\tpluginId?: string,\n\tprocedureName?: string,\n\toperation?: string\n): PluginRuntimeError => {\n\treturn new PluginRuntimeError({\n\t\tpluginId,\n\t\toperation,\n\t\tprocedureName,\n\t\tretryable: isRetryableORPCCode(orpcError.code),\n\t\tcause: orpcError as Error\n\t});\n};\n\n// Universal error converter for the runtime\nexport const toPluginRuntimeError = (\n\terror: unknown,\n\tpluginId?: string,\n\tprocedureName?: string,\n\toperation?: string,\n\tdefaultRetryable = false\n): PluginRuntimeError => {\n\tif (error instanceof ORPCError) {\n\t\treturn wrapORPCError(error, pluginId, procedureName, operation);\n\t}\n\n\tif (error instanceof PluginRuntimeError) {\n\t\treturn error;\n\t}\n\n\tconst message = extractErrorMessage(error);\n\n\tformatPluginError(pluginId, operation, message);\n\n\treturn new PluginRuntimeError({\n\t\tpluginId,\n\t\toperation,\n\t\tprocedureName,\n\t\tretryable: defaultRetryable || isRetryableError(message),\n\t\tcause: error instanceof Error ? error : new Error(message)\n\t});\n};\n"],"mappings":";;;;AAIA,IAAa,qBAAb,cAAwC,KAAK,YAAY,qBAAqB,CAM3E;AAEH,IAAa,wBAAb,cAA2C,KAAK,YAC/C,wBACA,CAIE;AAEH,IAAa,kBAAb,cAAqC,KAAK,YAAY,kBAAkB,CAIrE;AAEH,MAAM,uBAAuB,UAA2B;AACvD,KAAI,CAAC,MAAO,QAAO;AAEnB,KAAI,iBAAiB,OAAO;AAC3B,MAAI,MAAM,QAAS,QAAO,MAAM;AAChC,MAAK,MAAc,iBAAiB,MACnC,QAAO,oBAAqB,MAAc,MAAM;;AAIlD,KAAI,iBAAiB,kBAAkB,MAAM,QAAQ,OACpD,QAAO,MAAM,OAAO,KAAI,MAAK,oBAAoB,EAAE,CAAC,CAAC,KAAK,KAAK;AAGhE,KAAI,OAAO,UAAU,YAAY,aAAa,MAC7C,QAAO,OAAQ,MAAc,QAAQ;AAGtC,QAAO,OAAO,MAAM;;AAGrB,MAAM,qBACL,UACA,WACA,YACU;CACV,MAAMA,QAAkB,EAAE;AAE1B,OAAM,KAAK,qBAAqB,IAAI,OAAO,GAAG,GAAG;AACjD,KAAI,SAAU,OAAM,KAAK,cAAc,WAAW;AAClD,KAAI,UAAW,OAAM,KAAK,cAAc,YAAY;AACpD,OAAM,KAAK,IAAI;AAEf,KAAI,QAAQ,SAAS,eAAe,EAAE;AACrC,QAAM,KAAK,0BAA0B;AACrC,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,wCAAwC;AACnD,QAAM,KAAK,iCAAiC;YAClC,QAAQ,SAAS,YAAY,EAAE;AACzC,QAAM,KAAK,sBAAsB;AACjC,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,oDAAoD;YACrD,QAAQ,SAAS,YAAY,IAAI,QAAQ,SAAS,UAAU,EAAE;AACxE,QAAM,KAAK,0BAA0B;AACrC,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,2CAA2C;YAC5C,QAAQ,SAAS,SAAS,IAAI,QAAQ,SAAS,aAAa,EAAE;AACxE,QAAM,KAAK,yBAAyB;AACpC,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,8CAA8C;YAC/C,QAAQ,SAAS,MAAM,IAAI,QAAQ,SAAS,eAAe,EAAE;AACvE,QAAM,KAAK,6BAA6B;AACxC,QAAM,KAAK,MAAM;AACjB,QAAM,KAAK,wCAAwC;OAEnD,OAAM,KAAK,QAAQ,UAAU;AAG9B,OAAM,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI;AAElC,SAAQ,MAAM,MAAM,KAAK,KAAK,CAAC;;AAGhC,MAAM,oBAAoB,YAA6B;AAEtD,QAD0B;EAAC;EAAa;EAAc;EAAW;EAAO;EAAM,CACrD,MAAK,MAAK,QAAQ,aAAa,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;;AAIpF,MAAa,uBAAuB,SAA0B;AAC7D,SAAQ,MAAR;EACC,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,UACJ,QAAO;EACR,QACC,QAAO;;;AAKV,MAAa,iBACZ,WACA,UACA,eACA,cACwB;AACxB,QAAO,IAAI,mBAAmB;EAC7B;EACA;EACA;EACA,WAAW,oBAAoB,UAAU,KAAK;EAC9C,OAAO;EACP,CAAC;;AAIH,MAAa,wBACZ,OACA,UACA,eACA,WACA,mBAAmB,UACK;AACxB,KAAI,iBAAiB,UACpB,QAAO,cAAc,OAAO,UAAU,eAAe,UAAU;AAGhE,KAAI,iBAAiB,mBACpB,QAAO;CAGR,MAAM,UAAU,oBAAoB,MAAM;AAE1C,mBAAkB,UAAU,WAAW,QAAQ;AAE/C,QAAO,IAAI,mBAAmB;EAC7B;EACA;EACA;EACA,WAAW,oBAAoB,iBAAiB,QAAQ;EACxD,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,QAAQ;EAC1D,CAAC"}
|
package/dist/runtime/index.cjs
CHANGED
|
@@ -1,6 +1,158 @@
|
|
|
1
|
-
const
|
|
2
|
-
require('
|
|
3
|
-
require('
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_errors = require('./errors.cjs');
|
|
3
|
+
const require_plugin_service = require('./services/plugin.service.cjs');
|
|
4
|
+
let effect = require("effect");
|
|
5
|
+
let __orpc_server = require("@orpc/server");
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
+
//#region src/runtime/index.ts
|
|
8
|
+
var PluginRuntime = class {
|
|
9
|
+
["__registryType"];
|
|
10
|
+
pluginCache = /* @__PURE__ */ new Map();
|
|
11
|
+
constructor(runtime, registry) {
|
|
12
|
+
this.runtime = runtime;
|
|
13
|
+
this.registry = registry;
|
|
14
|
+
}
|
|
15
|
+
generateCacheKey(pluginId, config) {
|
|
16
|
+
return `${pluginId}:${effect.Hash.structure(config).toString()}`;
|
|
17
|
+
}
|
|
18
|
+
validatePluginId(pluginId) {
|
|
19
|
+
if (!(pluginId in this.registry)) return effect.Effect.fail(new require_errors.PluginRuntimeError({
|
|
20
|
+
pluginId: String(pluginId),
|
|
21
|
+
operation: "validate-plugin-id",
|
|
22
|
+
cause: /* @__PURE__ */ new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),
|
|
23
|
+
retryable: false
|
|
24
|
+
}));
|
|
25
|
+
return effect.Effect.succeed(String(pluginId));
|
|
26
|
+
}
|
|
27
|
+
async runPromise(effect$1) {
|
|
28
|
+
const exit = await this.runtime.runPromiseExit(effect$1);
|
|
29
|
+
if (effect.Exit.isFailure(exit)) {
|
|
30
|
+
const error = effect.Cause.failureOption(exit.cause);
|
|
31
|
+
if (effect.Option.isSome(error)) throw error.value;
|
|
32
|
+
throw effect.Cause.squash(exit.cause);
|
|
33
|
+
}
|
|
34
|
+
return exit.value;
|
|
35
|
+
}
|
|
36
|
+
async usePlugin(pluginId, config) {
|
|
37
|
+
const cacheKey = this.generateCacheKey(pluginId, config);
|
|
38
|
+
let cachedPlugin = this.pluginCache.get(cacheKey);
|
|
39
|
+
if (!cachedPlugin) {
|
|
40
|
+
const operation = effect.Effect.gen(this, function* () {
|
|
41
|
+
const pluginService = yield* require_plugin_service.PluginService;
|
|
42
|
+
const validatedId = yield* this.validatePluginId(pluginId);
|
|
43
|
+
const ctor = yield* pluginService.loadPlugin(validatedId);
|
|
44
|
+
const instance = yield* pluginService.instantiatePlugin(pluginId, ctor);
|
|
45
|
+
return yield* pluginService.initializePlugin(instance, config);
|
|
46
|
+
}).pipe(effect.Effect.provide(this.runtime));
|
|
47
|
+
cachedPlugin = effect.Effect.cached(operation).pipe(effect.Effect.flatten);
|
|
48
|
+
this.pluginCache.set(cacheKey, cachedPlugin);
|
|
49
|
+
}
|
|
50
|
+
const initialized = await this.runPromise(cachedPlugin);
|
|
51
|
+
const router = initialized.plugin.createRouter(initialized.context);
|
|
52
|
+
return {
|
|
53
|
+
router,
|
|
54
|
+
client: (0, __orpc_server.createRouterClient)(router),
|
|
55
|
+
metadata: initialized.metadata,
|
|
56
|
+
initialized
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
async loadPlugin(pluginId) {
|
|
60
|
+
const effect$1 = effect.Effect.gen(function* () {
|
|
61
|
+
return yield* (yield* require_plugin_service.PluginService).loadPlugin(pluginId);
|
|
62
|
+
});
|
|
63
|
+
return this.runPromise(effect$1);
|
|
64
|
+
}
|
|
65
|
+
async instantiatePlugin(pluginId, loadedPlugin) {
|
|
66
|
+
const effect$1 = effect.Effect.gen(function* () {
|
|
67
|
+
return yield* (yield* require_plugin_service.PluginService).instantiatePlugin(pluginId, loadedPlugin);
|
|
68
|
+
});
|
|
69
|
+
return this.runPromise(effect$1);
|
|
70
|
+
}
|
|
71
|
+
async initializePlugin(instance, config) {
|
|
72
|
+
const effect$1 = effect.Effect.gen(function* () {
|
|
73
|
+
return yield* (yield* require_plugin_service.PluginService).initializePlugin(instance, config);
|
|
74
|
+
});
|
|
75
|
+
return this.runPromise(effect$1);
|
|
76
|
+
}
|
|
77
|
+
async shutdown() {
|
|
78
|
+
const effect$1 = effect.Effect.gen(function* () {
|
|
79
|
+
yield* (yield* require_plugin_service.PluginService).cleanup();
|
|
80
|
+
});
|
|
81
|
+
return this.runPromise(effect$1);
|
|
82
|
+
}
|
|
83
|
+
async evictPlugin(pluginId, config) {
|
|
84
|
+
const cacheKey = this.generateCacheKey(pluginId, config);
|
|
85
|
+
const effect$1 = effect.Effect.gen(this, function* () {
|
|
86
|
+
const pluginService = yield* require_plugin_service.PluginService;
|
|
87
|
+
const cachedPlugin = this.pluginCache.get(cacheKey);
|
|
88
|
+
if (cachedPlugin) {
|
|
89
|
+
this.pluginCache.delete(cacheKey);
|
|
90
|
+
const pluginResult = yield* cachedPlugin.pipe(effect.Effect.catchAll(() => effect.Effect.succeed(null)));
|
|
91
|
+
if (pluginResult) yield* pluginService.shutdownPlugin(pluginResult).pipe(effect.Effect.catchAll(() => effect.Effect.void));
|
|
92
|
+
}
|
|
93
|
+
}).pipe(effect.Effect.catchAll(() => effect.Effect.void));
|
|
94
|
+
return this.runPromise(effect$1);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Normalizes a remote URL to ensure it points to remoteEntry.js
|
|
99
|
+
* If the URL doesn't end with a file extension, appends /remoteEntry.js
|
|
100
|
+
*/
|
|
101
|
+
function normalizeRemoteUrl(url) {
|
|
102
|
+
if (!url) return url;
|
|
103
|
+
if (url.endsWith(".js")) return url;
|
|
104
|
+
return `${url.endsWith("/") ? url.slice(0, -1) : url}/remoteEntry.js`;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Extract plugin map (module constructors) from registry entries
|
|
108
|
+
*/
|
|
109
|
+
function extractPluginMap(registry) {
|
|
110
|
+
const pluginMap = {};
|
|
111
|
+
for (const [pluginId, entry] of Object.entries(registry)) if ("module" in entry && entry.module) pluginMap[pluginId] = entry.module;
|
|
112
|
+
return pluginMap;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Normalize registry entries - ensure remote URLs are properly formatted
|
|
116
|
+
*/
|
|
117
|
+
function normalizeRegistry(registry) {
|
|
118
|
+
const normalized = {};
|
|
119
|
+
for (const [pluginId, entry] of Object.entries(registry)) if ("module" in entry) normalized[pluginId] = {
|
|
120
|
+
...entry,
|
|
121
|
+
remote: entry.remote ? normalizeRemoteUrl(entry.remote) : void 0
|
|
122
|
+
};
|
|
123
|
+
else normalized[pluginId] = {
|
|
124
|
+
...entry,
|
|
125
|
+
remote: normalizeRemoteUrl(entry.remote)
|
|
126
|
+
};
|
|
127
|
+
return normalized;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Creates a plugin runtime with support for both module and remote plugin entries.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* // With module entries (types inferred automatically)
|
|
135
|
+
* const runtime = createPluginRuntime({
|
|
136
|
+
* registry: {
|
|
137
|
+
* telegram: { module: TelegramPlugin },
|
|
138
|
+
* gopher: { remote: "https://cdn.example.com/gopher/remoteEntry.js" }
|
|
139
|
+
* },
|
|
140
|
+
* secrets: { API_KEY: "..." }
|
|
141
|
+
* });
|
|
142
|
+
*
|
|
143
|
+
* // Types are automatically inferred from module entries!
|
|
144
|
+
* const { client } = await runtime.usePlugin("telegram", config);
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
function createPluginRuntime(config) {
|
|
148
|
+
const secrets = config.secrets || {};
|
|
149
|
+
const normalizedRegistry = normalizeRegistry(config.registry);
|
|
150
|
+
const pluginMap = extractPluginMap(config.registry);
|
|
151
|
+
const layer = require_plugin_service.PluginService.Live(normalizedRegistry, secrets, pluginMap);
|
|
152
|
+
return new PluginRuntime(effect.ManagedRuntime.make(layer), normalizedRegistry);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//#endregion
|
|
156
|
+
exports.PluginRuntime = PluginRuntime;
|
|
157
|
+
exports.createPluginRuntime = createPluginRuntime;
|
|
158
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["runtime: ManagedRuntime.ManagedRuntime<PluginService, never>","registry: PluginRegistry","Hash","Effect","PluginRuntimeError","effect","Exit","Cause","Option","PluginService","pluginMap: Record<string, AnyPluginConstructor>","normalized: Record<string, PluginRegistryEntry>","ManagedRuntime"],"sources":["../../src/runtime/index.ts"],"sourcesContent":["import { createRouterClient } from \"@orpc/server\";\nimport { Cause, Effect, Exit, Hash, ManagedRuntime, Option } from \"effect\";\nimport type {\n\tAnyPlugin,\n\tAnyPluginConstructor,\n\tInferRegistryFromEntries,\n\tInitializedPlugin,\n\tLoadedPlugin,\n\tPluginClientType,\n\tPluginConfigInput,\n\tPluginInstance,\n\tPluginRegistry,\n\tPluginRegistryEntry,\n\tPluginRouterType,\n\tPluginRuntimeConfig,\n\tRegisteredPlugin,\n\tRegisteredPlugins,\n\tUsePluginResult\n} from \"../types\";\nimport { PluginRuntimeError } from \"./errors\";\nimport { PluginService } from \"./services/plugin.service\";\n\nexport class PluginRuntime<R = RegisteredPlugins> {\n\treadonly ['__registryType']?: R;\n\t\n\tprivate pluginCache = new Map<string, Effect.Effect<InitializedPlugin<AnyPlugin>, PluginRuntimeError>>();\n\n\tconstructor(\n\t\tprivate runtime: ManagedRuntime.ManagedRuntime<PluginService, never>,\n\t\tprivate registry: PluginRegistry\n\t) { }\n\n\tprivate generateCacheKey(pluginId: string, config: unknown): string {\n\t\tconst configHash = Hash.structure(config as object).toString();\n\t\treturn `${pluginId}:${configHash}`;\n\t}\n\n\tprivate validatePluginId(\n\t\tpluginId: string\n\t): Effect.Effect<string, PluginRuntimeError> {\n\t\tif (!(pluginId in this.registry)) {\n\t\t\treturn Effect.fail(new PluginRuntimeError({\n\t\t\t\tpluginId: String(pluginId),\n\t\t\t\toperation: \"validate-plugin-id\",\n\t\t\t\tcause: new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),\n\t\t\t\tretryable: false,\n\t\t\t}));\n\t\t}\n\t\treturn Effect.succeed(String(pluginId));\n\t}\n\n\tprivate async runPromise<A, E>(\n\t\teffect: Effect.Effect<A, E, PluginService>\n\t): Promise<A> {\n\t\tconst exit = await this.runtime.runPromiseExit(effect);\n\n\t\tif (Exit.isFailure(exit)) {\n\t\t\tconst error = Cause.failureOption(exit.cause);\n\t\t\tif (Option.isSome(error)) {\n\t\t\t\tthrow error.value;\n\t\t\t}\n\t\t\tthrow Cause.squash(exit.cause);\n\t\t}\n\n\t\treturn exit.value;\n\t}\n\n\tasync usePlugin<K extends keyof R & string>(\n\t\tpluginId: K,\n\t\tconfig: PluginConfigInput<R[K]>\n\t): Promise<UsePluginResult<K, R>> {\n\t\tconst cacheKey = this.generateCacheKey(pluginId, config);\n\n\t\tlet cachedPlugin = this.pluginCache.get(cacheKey);\n\t\tif (!cachedPlugin) {\n\t\t\tconst operation = Effect.gen(this, function* () {\n\t\t\t\tconst pluginService = yield* PluginService;\n\t\t\t\tconst validatedId = yield* this.validatePluginId(pluginId);\n\n\t\t\t\t// Load → Instantiate → Initialize\n\t\t\t\tconst ctor = yield* pluginService.loadPlugin(validatedId);\n\t\t\t\tconst instance = yield* pluginService.instantiatePlugin(pluginId, ctor);\n\t\t\t\tconst initialized = yield* pluginService.initializePlugin(instance, config);\n\n\t\t\t\treturn initialized;\n\t\t\t}).pipe(Effect.provide(this.runtime));\n\n\t\t\tcachedPlugin = Effect.cached(operation).pipe(Effect.flatten);\n\t\t\tthis.pluginCache.set(cacheKey, cachedPlugin);\n\t\t}\n\n\t\tconst initialized = await this.runPromise(cachedPlugin);\n\t\tconst router = initialized.plugin.createRouter(initialized.context);\n\t\tconst client = createRouterClient(router);\n\n\t\treturn {\n\t\t\trouter: router as PluginRouterType<R[K]>,\n\t\t\tclient: client as PluginClientType<R[K]>,\n\t\t\tmetadata: initialized.metadata,\n\t\t\tinitialized: initialized as InitializedPlugin<RegisteredPlugin<K, R>>\n\t\t} as UsePluginResult<K, R>;\n\t}\n\n\tasync loadPlugin<K extends keyof R & string>(\n\t\tpluginId: K\n\t): Promise<LoadedPlugin<RegisteredPlugin<K, R>>> {\n\t\tconst effect = Effect.gen(function* () {\n\t\t\tconst pluginService = yield* PluginService;\n\t\t\treturn yield* pluginService.loadPlugin(pluginId);\n\t\t});\n\t\treturn this.runPromise(effect) as Promise<LoadedPlugin<RegisteredPlugin<K, R>>>;\n\t}\n\n\tasync instantiatePlugin<K extends keyof R & string>(\n\t\tpluginId: K,\n\t\tloadedPlugin: LoadedPlugin<RegisteredPlugin<K, R>>\n\t): Promise<PluginInstance<RegisteredPlugin<K, R>>> {\n\t\tconst effect = Effect.gen(function* () {\n\t\t\tconst pluginService = yield* PluginService;\n\t\t\treturn yield* pluginService.instantiatePlugin(pluginId, loadedPlugin);\n\t\t});\n\t\treturn this.runPromise(effect) as Promise<PluginInstance<RegisteredPlugin<K, R>>>;\n\t}\n\n\tasync initializePlugin<T extends AnyPlugin>(\n\t\tinstance: PluginInstance<T>,\n\t\tconfig: any\n\t): Promise<InitializedPlugin<T>> {\n\t\tconst effect = Effect.gen(function* () {\n\t\t\tconst pluginService = yield* PluginService;\n\t\t\treturn yield* pluginService.initializePlugin(instance, config);\n\t\t});\n\t\treturn this.runPromise(effect);\n\t}\n\n\tasync shutdown(): Promise<void> {\n\t\tconst effect = Effect.gen(function* () {\n\t\t\tconst pluginService = yield* PluginService;\n\t\t\tyield* pluginService.cleanup();\n\t\t});\n\t\treturn this.runPromise(effect);\n\t}\n\n\tasync evictPlugin<K extends keyof R & string>(\n\t\tpluginId: K,\n\t\tconfig: PluginConfigInput<R[K]>\n\t): Promise<void> {\n\t\tconst cacheKey = this.generateCacheKey(pluginId, config);\n\n\t\tconst effect = Effect.gen(this, function* () {\n\t\t\tconst pluginService = yield* PluginService;\n\t\t\tconst cachedPlugin = this.pluginCache.get(cacheKey);\n\n\t\t\tif (cachedPlugin) {\n\t\t\t\tthis.pluginCache.delete(cacheKey);\n\n\t\t\t\tconst pluginResult = yield* cachedPlugin.pipe(\n\t\t\t\t\tEffect.catchAll(() => Effect.succeed(null))\n\t\t\t\t);\n\n\t\t\t\tif (pluginResult) {\n\t\t\t\t\tyield* pluginService.shutdownPlugin(pluginResult).pipe(\n\t\t\t\t\t\tEffect.catchAll(() => Effect.void)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}).pipe(Effect.catchAll(() => Effect.void));\n\n\t\treturn this.runPromise(effect);\n\t}\n}\n\n/**\n * Normalizes a remote URL to ensure it points to remoteEntry.js\n * If the URL doesn't end with a file extension, appends /remoteEntry.js\n */\nfunction normalizeRemoteUrl(url: string): string {\n\tif (!url) return url;\n\tif (url.endsWith('.js')) return url;\n\treturn `${url.endsWith('/') ? url.slice(0, -1) : url}/remoteEntry.js`;\n}\n\n/**\n * Extract plugin map (module constructors) from registry entries\n */\nfunction extractPluginMap(registry: Record<string, PluginRegistryEntry>): Record<string, AnyPluginConstructor> {\n\tconst pluginMap: Record<string, AnyPluginConstructor> = {};\n\t\n\tfor (const [pluginId, entry] of Object.entries(registry)) {\n\t\tif (\"module\" in entry && entry.module) {\n\t\t\tpluginMap[pluginId] = entry.module;\n\t\t}\n\t}\n\t\n\treturn pluginMap;\n}\n\n/**\n * Normalize registry entries - ensure remote URLs are properly formatted\n */\nfunction normalizeRegistry(registry: Record<string, PluginRegistryEntry>): PluginRegistry {\n\tconst normalized: Record<string, PluginRegistryEntry> = {};\n\t\n\tfor (const [pluginId, entry] of Object.entries(registry)) {\n\t\tif (\"module\" in entry) {\n\t\t\tnormalized[pluginId] = {\n\t\t\t\t...entry,\n\t\t\t\tremote: entry.remote ? normalizeRemoteUrl(entry.remote) : undefined,\n\t\t\t};\n\t\t} else {\n\t\t\tnormalized[pluginId] = {\n\t\t\t\t...entry,\n\t\t\t\tremote: normalizeRemoteUrl(entry.remote),\n\t\t\t};\n\t\t}\n\t}\n\t\n\treturn normalized as PluginRegistry;\n}\n\n/**\n * Creates a plugin runtime with support for both module and remote plugin entries.\n * \n * @example\n * ```typescript\n * // With module entries (types inferred automatically)\n * const runtime = createPluginRuntime({\n * registry: {\n * telegram: { module: TelegramPlugin },\n * gopher: { remote: \"https://cdn.example.com/gopher/remoteEntry.js\" }\n * },\n * secrets: { API_KEY: \"...\" }\n * });\n * \n * // Types are automatically inferred from module entries!\n * const { client } = await runtime.usePlugin(\"telegram\", config);\n * ```\n */\nexport function createPluginRuntime<\n\tTRegistry extends Record<string, PluginRegistryEntry>\n>(\n\tconfig: PluginRuntimeConfig<TRegistry>\n): PluginRuntime<InferRegistryFromEntries<TRegistry>> {\n\tconst secrets = config.secrets || {};\n\tconst normalizedRegistry = normalizeRegistry(config.registry);\n\tconst pluginMap = extractPluginMap(config.registry);\n\n\tconst layer = PluginService.Live(normalizedRegistry, secrets, pluginMap);\n\tconst runtime = ManagedRuntime.make(layer);\n\n\treturn new PluginRuntime(runtime, normalizedRegistry) as PluginRuntime<InferRegistryFromEntries<TRegistry>>;\n}\n"],"mappings":";;;;;;;AAsBA,IAAa,gBAAb,MAAkD;CACjD,CAAU;CAEV,AAAQ,8BAAc,IAAI,KAA8E;CAExG,YACC,AAAQA,SACR,AAAQC,UACP;EAFO;EACA;;CAGT,AAAQ,iBAAiB,UAAkB,QAAyB;AAEnE,SAAO,GAAG,SAAS,GADAC,YAAK,UAAU,OAAiB,CAAC,UAAU;;CAI/D,AAAQ,iBACP,UAC4C;AAC5C,MAAI,EAAE,YAAY,KAAK,UACtB,QAAOC,cAAO,KAAK,IAAIC,kCAAmB;GACzC,UAAU,OAAO,SAAS;GAC1B,WAAW;GACX,uBAAO,IAAI,MAAM,cAAc,OAAO,SAAS,CAAC,0BAA0B;GAC1E,WAAW;GACX,CAAC,CAAC;AAEJ,SAAOD,cAAO,QAAQ,OAAO,SAAS,CAAC;;CAGxC,MAAc,WACb,UACa;EACb,MAAM,OAAO,MAAM,KAAK,QAAQ,eAAeE,SAAO;AAEtD,MAAIC,YAAK,UAAU,KAAK,EAAE;GACzB,MAAM,QAAQC,aAAM,cAAc,KAAK,MAAM;AAC7C,OAAIC,cAAO,OAAO,MAAM,CACvB,OAAM,MAAM;AAEb,SAAMD,aAAM,OAAO,KAAK,MAAM;;AAG/B,SAAO,KAAK;;CAGb,MAAM,UACL,UACA,QACiC;EACjC,MAAM,WAAW,KAAK,iBAAiB,UAAU,OAAO;EAExD,IAAI,eAAe,KAAK,YAAY,IAAI,SAAS;AACjD,MAAI,CAAC,cAAc;GAClB,MAAM,YAAYJ,cAAO,IAAI,MAAM,aAAa;IAC/C,MAAM,gBAAgB,OAAOM;IAC7B,MAAM,cAAc,OAAO,KAAK,iBAAiB,SAAS;IAG1D,MAAM,OAAO,OAAO,cAAc,WAAW,YAAY;IACzD,MAAM,WAAW,OAAO,cAAc,kBAAkB,UAAU,KAAK;AAGvE,WAFoB,OAAO,cAAc,iBAAiB,UAAU,OAAO;KAG1E,CAAC,KAAKN,cAAO,QAAQ,KAAK,QAAQ,CAAC;AAErC,kBAAeA,cAAO,OAAO,UAAU,CAAC,KAAKA,cAAO,QAAQ;AAC5D,QAAK,YAAY,IAAI,UAAU,aAAa;;EAG7C,MAAM,cAAc,MAAM,KAAK,WAAW,aAAa;EACvD,MAAM,SAAS,YAAY,OAAO,aAAa,YAAY,QAAQ;AAGnE,SAAO;GACE;GACR,8CAJiC,OAAO;GAKxC,UAAU,YAAY;GACT;GACb;;CAGF,MAAM,WACL,UACgD;EAChD,MAAME,WAASF,cAAO,IAAI,aAAa;AAEtC,UAAO,QADe,OAAOM,sCACD,WAAW,SAAS;IAC/C;AACF,SAAO,KAAK,WAAWJ,SAAO;;CAG/B,MAAM,kBACL,UACA,cACkD;EAClD,MAAMA,WAASF,cAAO,IAAI,aAAa;AAEtC,UAAO,QADe,OAAOM,sCACD,kBAAkB,UAAU,aAAa;IACpE;AACF,SAAO,KAAK,WAAWJ,SAAO;;CAG/B,MAAM,iBACL,UACA,QACgC;EAChC,MAAMA,WAASF,cAAO,IAAI,aAAa;AAEtC,UAAO,QADe,OAAOM,sCACD,iBAAiB,UAAU,OAAO;IAC7D;AACF,SAAO,KAAK,WAAWJ,SAAO;;CAG/B,MAAM,WAA0B;EAC/B,MAAMA,WAASF,cAAO,IAAI,aAAa;AAEtC,WADsB,OAAOM,sCACR,SAAS;IAC7B;AACF,SAAO,KAAK,WAAWJ,SAAO;;CAG/B,MAAM,YACL,UACA,QACgB;EAChB,MAAM,WAAW,KAAK,iBAAiB,UAAU,OAAO;EAExD,MAAMA,WAASF,cAAO,IAAI,MAAM,aAAa;GAC5C,MAAM,gBAAgB,OAAOM;GAC7B,MAAM,eAAe,KAAK,YAAY,IAAI,SAAS;AAEnD,OAAI,cAAc;AACjB,SAAK,YAAY,OAAO,SAAS;IAEjC,MAAM,eAAe,OAAO,aAAa,KACxCN,cAAO,eAAeA,cAAO,QAAQ,KAAK,CAAC,CAC3C;AAED,QAAI,aACH,QAAO,cAAc,eAAe,aAAa,CAAC,KACjDA,cAAO,eAAeA,cAAO,KAAK,CAClC;;IAGF,CAAC,KAAKA,cAAO,eAAeA,cAAO,KAAK,CAAC;AAE3C,SAAO,KAAK,WAAWE,SAAO;;;;;;;AAQhC,SAAS,mBAAmB,KAAqB;AAChD,KAAI,CAAC,IAAK,QAAO;AACjB,KAAI,IAAI,SAAS,MAAM,CAAE,QAAO;AAChC,QAAO,GAAG,IAAI,SAAS,IAAI,GAAG,IAAI,MAAM,GAAG,GAAG,GAAG,IAAI;;;;;AAMtD,SAAS,iBAAiB,UAAqF;CAC9G,MAAMK,YAAkD,EAAE;AAE1D,MAAK,MAAM,CAAC,UAAU,UAAU,OAAO,QAAQ,SAAS,CACvD,KAAI,YAAY,SAAS,MAAM,OAC9B,WAAU,YAAY,MAAM;AAI9B,QAAO;;;;;AAMR,SAAS,kBAAkB,UAA+D;CACzF,MAAMC,aAAkD,EAAE;AAE1D,MAAK,MAAM,CAAC,UAAU,UAAU,OAAO,QAAQ,SAAS,CACvD,KAAI,YAAY,MACf,YAAW,YAAY;EACtB,GAAG;EACH,QAAQ,MAAM,SAAS,mBAAmB,MAAM,OAAO,GAAG;EAC1D;KAED,YAAW,YAAY;EACtB,GAAG;EACH,QAAQ,mBAAmB,MAAM,OAAO;EACxC;AAIH,QAAO;;;;;;;;;;;;;;;;;;;;AAqBR,SAAgB,oBAGf,QACqD;CACrD,MAAM,UAAU,OAAO,WAAW,EAAE;CACpC,MAAM,qBAAqB,kBAAkB,OAAO,SAAS;CAC7D,MAAM,YAAY,iBAAiB,OAAO,SAAS;CAEnD,MAAM,QAAQF,qCAAc,KAAK,oBAAoB,SAAS,UAAU;AAGxE,QAAO,IAAI,cAFKG,sBAAe,KAAK,MAAM,EAER,mBAAmB"}
|
package/dist/runtime/index.d.cts
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
|
-
import "../
|
|
2
|
-
import "
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { AnyPlugin, InferRegistryFromEntries, InitializedPlugin, LoadedPlugin, PluginConfigInput, PluginInstance, PluginRegistry, PluginRegistryEntry, PluginRuntimeConfig, RegisteredPlugin, RegisteredPlugins, UsePluginResult } from "../types.cjs";
|
|
2
|
+
import { PluginService } from "./services/plugin.service.cjs";
|
|
3
|
+
import { ManagedRuntime } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/runtime/index.d.ts
|
|
6
|
+
declare class PluginRuntime<R = RegisteredPlugins> {
|
|
7
|
+
private runtime;
|
|
8
|
+
private registry;
|
|
9
|
+
readonly ['__registryType']?: R;
|
|
10
|
+
private pluginCache;
|
|
11
|
+
constructor(runtime: ManagedRuntime.ManagedRuntime<PluginService, never>, registry: PluginRegistry);
|
|
12
|
+
private generateCacheKey;
|
|
13
|
+
private validatePluginId;
|
|
14
|
+
private runPromise;
|
|
15
|
+
usePlugin<K extends keyof R & string>(pluginId: K, config: PluginConfigInput<R[K]>): Promise<UsePluginResult<K, R>>;
|
|
16
|
+
loadPlugin<K extends keyof R & string>(pluginId: K): Promise<LoadedPlugin<RegisteredPlugin<K, R>>>;
|
|
17
|
+
instantiatePlugin<K extends keyof R & string>(pluginId: K, loadedPlugin: LoadedPlugin<RegisteredPlugin<K, R>>): Promise<PluginInstance<RegisteredPlugin<K, R>>>;
|
|
18
|
+
initializePlugin<T extends AnyPlugin>(instance: PluginInstance<T>, config: any): Promise<InitializedPlugin<T>>;
|
|
19
|
+
shutdown(): Promise<void>;
|
|
20
|
+
evictPlugin<K extends keyof R & string>(pluginId: K, config: PluginConfigInput<R[K]>): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates a plugin runtime with support for both module and remote plugin entries.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // With module entries (types inferred automatically)
|
|
28
|
+
* const runtime = createPluginRuntime({
|
|
29
|
+
* registry: {
|
|
30
|
+
* telegram: { module: TelegramPlugin },
|
|
31
|
+
* gopher: { remote: "https://cdn.example.com/gopher/remoteEntry.js" }
|
|
32
|
+
* },
|
|
33
|
+
* secrets: { API_KEY: "..." }
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Types are automatically inferred from module entries!
|
|
37
|
+
* const { client } = await runtime.usePlugin("telegram", config);
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare function createPluginRuntime<TRegistry extends Record<string, PluginRegistryEntry>>(config: PluginRuntimeConfig<TRegistry>): PluginRuntime<InferRegistryFromEntries<TRegistry>>;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { PluginRuntime, createPluginRuntime };
|
|
43
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/runtime/index.ts"],"sourcesContent":[],"mappings":";;;;;cAsBa,kBAAkB;;EAAlB,QAAA,QAAa;EAAK,UAAA,gBAAA,EAAA,EACA,CADA;EACA,QAAA,WAAA;EAKkB,WAAA,CAAA,OAAA,EAA9B,cAAA,CAAe,cAAe,CAAA,aAAA,EAAA,KAAA,CAAA,EAAA,QAAA,EAC7B,cAD6B;EAA9B,QAAA,gBAAe;EACd,QAAA,gBAAA;EAsCa,QAAA,UAAA;EACrB,SAAA,CAAA,UAAA,MADqB,CACrB,GAAA,MAAA,CAAA,CAAA,QAAA,EAAA,CAAA,EAAA,MAAA,EACF,iBADE,CACgB,CADhB,CACkB,CADlB,CAAA,CAAA,CAAA,EAER,OAFQ,CAEA,eAFA,CAEgB,CAFhB,EAEmB,CAFnB,CAAA,CAAA;EACgB,UAAA,CAAA,UAAA,MAkCM,CAlCN,GAAA,MAAA,CAAA,CAAA,QAAA,EAmChB,CAnCgB,CAAA,EAoCxB,OApCwB,CAoChB,YApCgB,CAoCH,gBApCG,CAoCc,CApCd,EAoCiB,CApCjB,CAAA,CAAA,CAAA;EAAE,iBAAA,CAAA,UAAA,MA4CW,CA5CX,GAAA,MAAA,CAAA,CAAA,QAAA,EA6ClB,CA7CkB,EAAA,YAAA,EA8Cd,YA9Cc,CA8CD,gBA9CC,CA8CgB,CA9ChB,EA8CmB,CA9CnB,CAAA,CAAA,CAAA,EA+C1B,OA/C0B,CA+ClB,cA/CkB,CA+CH,gBA/CG,CA+Cc,CA/Cd,EA+CiB,CA/CjB,CAAA,CAAA,CAAA;EAApB,gBAAA,CAAA,UAuDwB,SAvDxB,CAAA,CAAA,QAAA,EAwDE,cAxDF,CAwDiB,CAxDjB,CAAA,EAAA,MAAA,EAAA,GAAA,CAAA,EA0DN,OA1DM,CA0DE,iBA1DF,CA0DoB,CA1DpB,CAAA,CAAA;EACkB,QAAA,CAAA,CAAA,EAiET,OAjES,CAAA,IAAA,CAAA;EAAG,WAAA,CAAA,UAAA,MAyEI,CAzEJ,GAAA,MAAA,CAAA,CAAA,QAAA,EA0EnB,CA1EmB,EAAA,MAAA,EA2ErB,iBA3EqB,CA2EH,CA3EG,CA2ED,CA3EC,CAAA,CAAA,CAAA,EA4E3B,OA5E2B,CAAA,IAAA,CAAA;;;;;;;;;;;;;;;;;;;;AA8C3B,iBA0HY,mBA1HZ,CAAA,kBA2He,MA3Hf,CAAA,MAAA,EA2H8B,mBA3H9B,CAAA,CAAA,CAAA,MAAA,EA6HK,mBA7HL,CA6HyB,SA7HzB,CAAA,CAAA,EA8HD,aA9HC,CA8Ha,wBA9Hb,CA8HsC,SA9HtC,CAAA,CAAA"}
|
package/dist/runtime/index.d.mts
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
|
-
import "../
|
|
2
|
-
import "
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { AnyPlugin, InferRegistryFromEntries, InitializedPlugin, LoadedPlugin, PluginConfigInput, PluginInstance, PluginRegistry, PluginRegistryEntry, PluginRuntimeConfig, RegisteredPlugin, RegisteredPlugins, UsePluginResult } from "../types.mjs";
|
|
2
|
+
import { PluginService } from "./services/plugin.service.mjs";
|
|
3
|
+
import { ManagedRuntime } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/runtime/index.d.ts
|
|
6
|
+
declare class PluginRuntime<R = RegisteredPlugins> {
|
|
7
|
+
private runtime;
|
|
8
|
+
private registry;
|
|
9
|
+
readonly ['__registryType']?: R;
|
|
10
|
+
private pluginCache;
|
|
11
|
+
constructor(runtime: ManagedRuntime.ManagedRuntime<PluginService, never>, registry: PluginRegistry);
|
|
12
|
+
private generateCacheKey;
|
|
13
|
+
private validatePluginId;
|
|
14
|
+
private runPromise;
|
|
15
|
+
usePlugin<K extends keyof R & string>(pluginId: K, config: PluginConfigInput<R[K]>): Promise<UsePluginResult<K, R>>;
|
|
16
|
+
loadPlugin<K extends keyof R & string>(pluginId: K): Promise<LoadedPlugin<RegisteredPlugin<K, R>>>;
|
|
17
|
+
instantiatePlugin<K extends keyof R & string>(pluginId: K, loadedPlugin: LoadedPlugin<RegisteredPlugin<K, R>>): Promise<PluginInstance<RegisteredPlugin<K, R>>>;
|
|
18
|
+
initializePlugin<T extends AnyPlugin>(instance: PluginInstance<T>, config: any): Promise<InitializedPlugin<T>>;
|
|
19
|
+
shutdown(): Promise<void>;
|
|
20
|
+
evictPlugin<K extends keyof R & string>(pluginId: K, config: PluginConfigInput<R[K]>): Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Creates a plugin runtime with support for both module and remote plugin entries.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // With module entries (types inferred automatically)
|
|
28
|
+
* const runtime = createPluginRuntime({
|
|
29
|
+
* registry: {
|
|
30
|
+
* telegram: { module: TelegramPlugin },
|
|
31
|
+
* gopher: { remote: "https://cdn.example.com/gopher/remoteEntry.js" }
|
|
32
|
+
* },
|
|
33
|
+
* secrets: { API_KEY: "..." }
|
|
34
|
+
* });
|
|
35
|
+
*
|
|
36
|
+
* // Types are automatically inferred from module entries!
|
|
37
|
+
* const { client } = await runtime.usePlugin("telegram", config);
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
declare function createPluginRuntime<TRegistry extends Record<string, PluginRegistryEntry>>(config: PluginRuntimeConfig<TRegistry>): PluginRuntime<InferRegistryFromEntries<TRegistry>>;
|
|
41
|
+
//#endregion
|
|
42
|
+
export { PluginRuntime, createPluginRuntime };
|
|
43
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/runtime/index.ts"],"sourcesContent":[],"mappings":";;;;;cAsBa,kBAAkB;;EAAlB,QAAA,QAAa;EAAK,UAAA,gBAAA,EAAA,EACA,CADA;EACA,QAAA,WAAA;EAKkB,WAAA,CAAA,OAAA,EAA9B,cAAA,CAAe,cAAe,CAAA,aAAA,EAAA,KAAA,CAAA,EAAA,QAAA,EAC7B,cAD6B;EAA9B,QAAA,gBAAe;EACd,QAAA,gBAAA;EAsCa,QAAA,UAAA;EACrB,SAAA,CAAA,UAAA,MADqB,CACrB,GAAA,MAAA,CAAA,CAAA,QAAA,EAAA,CAAA,EAAA,MAAA,EACF,iBADE,CACgB,CADhB,CACkB,CADlB,CAAA,CAAA,CAAA,EAER,OAFQ,CAEA,eAFA,CAEgB,CAFhB,EAEmB,CAFnB,CAAA,CAAA;EACgB,UAAA,CAAA,UAAA,MAkCM,CAlCN,GAAA,MAAA,CAAA,CAAA,QAAA,EAmChB,CAnCgB,CAAA,EAoCxB,OApCwB,CAoChB,YApCgB,CAoCH,gBApCG,CAoCc,CApCd,EAoCiB,CApCjB,CAAA,CAAA,CAAA;EAAE,iBAAA,CAAA,UAAA,MA4CW,CA5CX,GAAA,MAAA,CAAA,CAAA,QAAA,EA6ClB,CA7CkB,EAAA,YAAA,EA8Cd,YA9Cc,CA8CD,gBA9CC,CA8CgB,CA9ChB,EA8CmB,CA9CnB,CAAA,CAAA,CAAA,EA+C1B,OA/C0B,CA+ClB,cA/CkB,CA+CH,gBA/CG,CA+Cc,CA/Cd,EA+CiB,CA/CjB,CAAA,CAAA,CAAA;EAApB,gBAAA,CAAA,UAuDwB,SAvDxB,CAAA,CAAA,QAAA,EAwDE,cAxDF,CAwDiB,CAxDjB,CAAA,EAAA,MAAA,EAAA,GAAA,CAAA,EA0DN,OA1DM,CA0DE,iBA1DF,CA0DoB,CA1DpB,CAAA,CAAA;EACkB,QAAA,CAAA,CAAA,EAiET,OAjES,CAAA,IAAA,CAAA;EAAG,WAAA,CAAA,UAAA,MAyEI,CAzEJ,GAAA,MAAA,CAAA,CAAA,QAAA,EA0EnB,CA1EmB,EAAA,MAAA,EA2ErB,iBA3EqB,CA2EH,CA3EG,CA2ED,CA3EC,CAAA,CAAA,CAAA,EA4E3B,OA5E2B,CAAA,IAAA,CAAA;;;;;;;;;;;;;;;;;;;;AA8C3B,iBA0HY,mBA1HZ,CAAA,kBA2He,MA3Hf,CAAA,MAAA,EA2H8B,mBA3H9B,CAAA,CAAA,CAAA,MAAA,EA6HK,mBA7HL,CA6HyB,SA7HzB,CAAA,CAAA,EA8HD,aA9HC,CA8Ha,wBA9Hb,CA8HsC,SA9HtC,CAAA,CAAA"}
|
package/dist/runtime/index.mjs
CHANGED
|
@@ -1,5 +1,156 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "
|
|
3
|
-
import "
|
|
1
|
+
import { PluginRuntimeError } from "./errors.mjs";
|
|
2
|
+
import { PluginService } from "./services/plugin.service.mjs";
|
|
3
|
+
import { Cause, Effect, Exit, Hash, ManagedRuntime, Option } from "effect";
|
|
4
|
+
import { createRouterClient } from "@orpc/server";
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
//#region src/runtime/index.ts
|
|
7
|
+
var PluginRuntime = class {
|
|
8
|
+
["__registryType"];
|
|
9
|
+
pluginCache = /* @__PURE__ */ new Map();
|
|
10
|
+
constructor(runtime, registry) {
|
|
11
|
+
this.runtime = runtime;
|
|
12
|
+
this.registry = registry;
|
|
13
|
+
}
|
|
14
|
+
generateCacheKey(pluginId, config) {
|
|
15
|
+
return `${pluginId}:${Hash.structure(config).toString()}`;
|
|
16
|
+
}
|
|
17
|
+
validatePluginId(pluginId) {
|
|
18
|
+
if (!(pluginId in this.registry)) return Effect.fail(new PluginRuntimeError({
|
|
19
|
+
pluginId: String(pluginId),
|
|
20
|
+
operation: "validate-plugin-id",
|
|
21
|
+
cause: /* @__PURE__ */ new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),
|
|
22
|
+
retryable: false
|
|
23
|
+
}));
|
|
24
|
+
return Effect.succeed(String(pluginId));
|
|
25
|
+
}
|
|
26
|
+
async runPromise(effect) {
|
|
27
|
+
const exit = await this.runtime.runPromiseExit(effect);
|
|
28
|
+
if (Exit.isFailure(exit)) {
|
|
29
|
+
const error = Cause.failureOption(exit.cause);
|
|
30
|
+
if (Option.isSome(error)) throw error.value;
|
|
31
|
+
throw Cause.squash(exit.cause);
|
|
32
|
+
}
|
|
33
|
+
return exit.value;
|
|
34
|
+
}
|
|
35
|
+
async usePlugin(pluginId, config) {
|
|
36
|
+
const cacheKey = this.generateCacheKey(pluginId, config);
|
|
37
|
+
let cachedPlugin = this.pluginCache.get(cacheKey);
|
|
38
|
+
if (!cachedPlugin) {
|
|
39
|
+
const operation = Effect.gen(this, function* () {
|
|
40
|
+
const pluginService = yield* PluginService;
|
|
41
|
+
const validatedId = yield* this.validatePluginId(pluginId);
|
|
42
|
+
const ctor = yield* pluginService.loadPlugin(validatedId);
|
|
43
|
+
const instance = yield* pluginService.instantiatePlugin(pluginId, ctor);
|
|
44
|
+
return yield* pluginService.initializePlugin(instance, config);
|
|
45
|
+
}).pipe(Effect.provide(this.runtime));
|
|
46
|
+
cachedPlugin = Effect.cached(operation).pipe(Effect.flatten);
|
|
47
|
+
this.pluginCache.set(cacheKey, cachedPlugin);
|
|
48
|
+
}
|
|
49
|
+
const initialized = await this.runPromise(cachedPlugin);
|
|
50
|
+
const router = initialized.plugin.createRouter(initialized.context);
|
|
51
|
+
return {
|
|
52
|
+
router,
|
|
53
|
+
client: createRouterClient(router),
|
|
54
|
+
metadata: initialized.metadata,
|
|
55
|
+
initialized
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async loadPlugin(pluginId) {
|
|
59
|
+
const effect = Effect.gen(function* () {
|
|
60
|
+
return yield* (yield* PluginService).loadPlugin(pluginId);
|
|
61
|
+
});
|
|
62
|
+
return this.runPromise(effect);
|
|
63
|
+
}
|
|
64
|
+
async instantiatePlugin(pluginId, loadedPlugin) {
|
|
65
|
+
const effect = Effect.gen(function* () {
|
|
66
|
+
return yield* (yield* PluginService).instantiatePlugin(pluginId, loadedPlugin);
|
|
67
|
+
});
|
|
68
|
+
return this.runPromise(effect);
|
|
69
|
+
}
|
|
70
|
+
async initializePlugin(instance, config) {
|
|
71
|
+
const effect = Effect.gen(function* () {
|
|
72
|
+
return yield* (yield* PluginService).initializePlugin(instance, config);
|
|
73
|
+
});
|
|
74
|
+
return this.runPromise(effect);
|
|
75
|
+
}
|
|
76
|
+
async shutdown() {
|
|
77
|
+
const effect = Effect.gen(function* () {
|
|
78
|
+
yield* (yield* PluginService).cleanup();
|
|
79
|
+
});
|
|
80
|
+
return this.runPromise(effect);
|
|
81
|
+
}
|
|
82
|
+
async evictPlugin(pluginId, config) {
|
|
83
|
+
const cacheKey = this.generateCacheKey(pluginId, config);
|
|
84
|
+
const effect = Effect.gen(this, function* () {
|
|
85
|
+
const pluginService = yield* PluginService;
|
|
86
|
+
const cachedPlugin = this.pluginCache.get(cacheKey);
|
|
87
|
+
if (cachedPlugin) {
|
|
88
|
+
this.pluginCache.delete(cacheKey);
|
|
89
|
+
const pluginResult = yield* cachedPlugin.pipe(Effect.catchAll(() => Effect.succeed(null)));
|
|
90
|
+
if (pluginResult) yield* pluginService.shutdownPlugin(pluginResult).pipe(Effect.catchAll(() => Effect.void));
|
|
91
|
+
}
|
|
92
|
+
}).pipe(Effect.catchAll(() => Effect.void));
|
|
93
|
+
return this.runPromise(effect);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Normalizes a remote URL to ensure it points to remoteEntry.js
|
|
98
|
+
* If the URL doesn't end with a file extension, appends /remoteEntry.js
|
|
99
|
+
*/
|
|
100
|
+
function normalizeRemoteUrl(url) {
|
|
101
|
+
if (!url) return url;
|
|
102
|
+
if (url.endsWith(".js")) return url;
|
|
103
|
+
return `${url.endsWith("/") ? url.slice(0, -1) : url}/remoteEntry.js`;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Extract plugin map (module constructors) from registry entries
|
|
107
|
+
*/
|
|
108
|
+
function extractPluginMap(registry) {
|
|
109
|
+
const pluginMap = {};
|
|
110
|
+
for (const [pluginId, entry] of Object.entries(registry)) if ("module" in entry && entry.module) pluginMap[pluginId] = entry.module;
|
|
111
|
+
return pluginMap;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Normalize registry entries - ensure remote URLs are properly formatted
|
|
115
|
+
*/
|
|
116
|
+
function normalizeRegistry(registry) {
|
|
117
|
+
const normalized = {};
|
|
118
|
+
for (const [pluginId, entry] of Object.entries(registry)) if ("module" in entry) normalized[pluginId] = {
|
|
119
|
+
...entry,
|
|
120
|
+
remote: entry.remote ? normalizeRemoteUrl(entry.remote) : void 0
|
|
121
|
+
};
|
|
122
|
+
else normalized[pluginId] = {
|
|
123
|
+
...entry,
|
|
124
|
+
remote: normalizeRemoteUrl(entry.remote)
|
|
125
|
+
};
|
|
126
|
+
return normalized;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Creates a plugin runtime with support for both module and remote plugin entries.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* ```typescript
|
|
133
|
+
* // With module entries (types inferred automatically)
|
|
134
|
+
* const runtime = createPluginRuntime({
|
|
135
|
+
* registry: {
|
|
136
|
+
* telegram: { module: TelegramPlugin },
|
|
137
|
+
* gopher: { remote: "https://cdn.example.com/gopher/remoteEntry.js" }
|
|
138
|
+
* },
|
|
139
|
+
* secrets: { API_KEY: "..." }
|
|
140
|
+
* });
|
|
141
|
+
*
|
|
142
|
+
* // Types are automatically inferred from module entries!
|
|
143
|
+
* const { client } = await runtime.usePlugin("telegram", config);
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
function createPluginRuntime(config) {
|
|
147
|
+
const secrets = config.secrets || {};
|
|
148
|
+
const normalizedRegistry = normalizeRegistry(config.registry);
|
|
149
|
+
const pluginMap = extractPluginMap(config.registry);
|
|
150
|
+
const layer = PluginService.Live(normalizedRegistry, secrets, pluginMap);
|
|
151
|
+
return new PluginRuntime(ManagedRuntime.make(layer), normalizedRegistry);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
//#endregion
|
|
155
|
+
export { PluginRuntime, createPluginRuntime };
|
|
156
|
+
//# sourceMappingURL=index.mjs.map
|