every-plugin 0.5.0 → 0.5.1

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.
Files changed (196) hide show
  1. package/dist/{chunk-zltIcp7o.cjs → _virtual/rolldown_runtime.cjs} +3 -18
  2. package/dist/{chunk-QQAxy9l9.mjs → _virtual/rolldown_runtime.mjs} +1 -1
  3. package/dist/build/rspack/dev-server-middleware.cjs +201 -0
  4. package/dist/build/rspack/dev-server-middleware.cjs.map +1 -0
  5. package/dist/build/rspack/dev-server-middleware.mjs +200 -0
  6. package/dist/build/rspack/dev-server-middleware.mjs.map +1 -0
  7. package/dist/build/rspack/index.cjs +2 -362
  8. package/dist/build/rspack/index.d.cts +2 -20
  9. package/dist/build/rspack/index.d.mts +2 -20
  10. package/dist/build/rspack/index.mjs +2 -360
  11. package/dist/build/rspack/module-federation.cjs +47 -0
  12. package/dist/build/rspack/module-federation.cjs.map +1 -0
  13. package/dist/build/rspack/module-federation.mjs +47 -0
  14. package/dist/build/rspack/module-federation.mjs.map +1 -0
  15. package/dist/build/rspack/plugin.cjs +90 -0
  16. package/dist/build/rspack/plugin.cjs.map +1 -0
  17. package/dist/build/rspack/plugin.d.cts +20 -0
  18. package/dist/build/rspack/plugin.d.cts.map +1 -0
  19. package/dist/build/rspack/plugin.d.mts +20 -0
  20. package/dist/build/rspack/plugin.d.mts.map +1 -0
  21. package/dist/build/rspack/plugin.mjs +89 -0
  22. package/dist/build/rspack/plugin.mjs.map +1 -0
  23. package/dist/build/rspack/utils.cjs +41 -0
  24. package/dist/build/rspack/utils.cjs.map +1 -0
  25. package/dist/build/rspack/utils.mjs +38 -0
  26. package/dist/build/rspack/utils.mjs.map +1 -0
  27. package/dist/errors.cjs +62 -3
  28. package/dist/errors.cjs.map +1 -0
  29. package/dist/errors.d.cts +75 -3
  30. package/dist/errors.d.cts.map +1 -0
  31. package/dist/errors.d.mts +75 -3
  32. package/dist/errors.d.mts.map +1 -0
  33. package/dist/errors.mjs +62 -3
  34. package/dist/errors.mjs.map +1 -0
  35. package/dist/index.cjs +8 -55
  36. package/dist/index.d.cts +6 -5
  37. package/dist/index.d.mts +6 -5
  38. package/dist/index.mjs +5 -51
  39. package/dist/orpc.cjs +1 -1
  40. package/dist/{package-DyTuSutr.cjs → package.cjs} +22 -7
  41. package/dist/package.cjs.map +1 -0
  42. package/dist/{package-CaRYwbRi.mjs → package.mjs} +22 -5
  43. package/dist/package.mjs.map +1 -0
  44. package/dist/plugin.cjs +48 -0
  45. package/dist/plugin.cjs.map +1 -0
  46. package/dist/plugin.d.cts +62 -0
  47. package/dist/plugin.d.cts.map +1 -0
  48. package/dist/plugin.d.mts +62 -0
  49. package/dist/plugin.d.mts.map +1 -0
  50. package/dist/plugin.mjs +47 -0
  51. package/dist/plugin.mjs.map +1 -0
  52. package/dist/runtime/errors.cjs +45 -0
  53. package/dist/runtime/errors.cjs.map +1 -0
  54. package/dist/runtime/errors.d.cts +27 -0
  55. package/dist/runtime/errors.d.cts.map +1 -0
  56. package/dist/runtime/errors.d.mts +27 -0
  57. package/dist/runtime/errors.d.mts.map +1 -0
  58. package/dist/runtime/errors.mjs +41 -0
  59. package/dist/runtime/errors.mjs.map +1 -0
  60. package/dist/runtime/index.cjs +157 -5
  61. package/dist/runtime/index.cjs.map +1 -0
  62. package/dist/runtime/index.d.cts +43 -5
  63. package/dist/runtime/index.d.cts.map +1 -0
  64. package/dist/runtime/index.d.mts +43 -5
  65. package/dist/runtime/index.d.mts.map +1 -0
  66. package/dist/runtime/index.mjs +155 -4
  67. package/dist/runtime/index.mjs.map +1 -0
  68. package/dist/runtime/services/module-federation.service.cjs +143 -0
  69. package/dist/runtime/services/module-federation.service.cjs.map +1 -0
  70. package/dist/runtime/services/module-federation.service.d.cts +15 -0
  71. package/dist/runtime/services/module-federation.service.d.cts.map +1 -0
  72. package/dist/runtime/services/module-federation.service.d.mts +15 -0
  73. package/dist/runtime/services/module-federation.service.d.mts.map +1 -0
  74. package/dist/runtime/services/module-federation.service.mjs +143 -0
  75. package/dist/runtime/services/module-federation.service.mjs.map +1 -0
  76. package/dist/runtime/services/normalize.cjs +22 -2
  77. package/dist/runtime/services/normalize.cjs.map +1 -0
  78. package/dist/runtime/services/normalize.d.cts +21 -2
  79. package/dist/runtime/services/normalize.d.cts.map +1 -0
  80. package/dist/runtime/services/normalize.d.mts +21 -2
  81. package/dist/runtime/services/normalize.d.mts.map +1 -0
  82. package/dist/runtime/services/normalize.mjs +21 -2
  83. package/dist/runtime/services/normalize.mjs.map +1 -0
  84. package/dist/runtime/services/plugin-lifecycle.service.cjs +33 -0
  85. package/dist/runtime/services/plugin-lifecycle.service.cjs.map +1 -0
  86. package/dist/runtime/services/plugin-lifecycle.service.d.cts +17 -0
  87. package/dist/runtime/services/plugin-lifecycle.service.d.cts.map +1 -0
  88. package/dist/runtime/services/plugin-lifecycle.service.d.mts +17 -0
  89. package/dist/runtime/services/plugin-lifecycle.service.d.mts.map +1 -0
  90. package/dist/runtime/services/plugin-lifecycle.service.mjs +32 -0
  91. package/dist/runtime/services/plugin-lifecycle.service.mjs.map +1 -0
  92. package/dist/runtime/services/plugin-loader.service.cjs +125 -0
  93. package/dist/runtime/services/plugin-loader.service.cjs.map +1 -0
  94. package/dist/runtime/services/plugin-loader.service.d.cts +54 -0
  95. package/dist/runtime/services/plugin-loader.service.d.cts.map +1 -0
  96. package/dist/runtime/services/plugin-loader.service.d.mts +54 -0
  97. package/dist/runtime/services/plugin-loader.service.d.mts.map +1 -0
  98. package/dist/runtime/services/plugin-loader.service.mjs +121 -0
  99. package/dist/runtime/services/plugin-loader.service.mjs.map +1 -0
  100. package/dist/runtime/services/plugin.service.cjs +33 -0
  101. package/dist/runtime/services/plugin.service.cjs.map +1 -0
  102. package/dist/runtime/services/plugin.service.d.cts +42 -0
  103. package/dist/runtime/services/plugin.service.d.cts.map +1 -0
  104. package/dist/runtime/services/plugin.service.d.mts +42 -0
  105. package/dist/runtime/services/plugin.service.d.mts.map +1 -0
  106. package/dist/runtime/services/plugin.service.mjs +32 -0
  107. package/dist/runtime/services/plugin.service.mjs.map +1 -0
  108. package/dist/runtime/services/secrets.service.cjs +50 -0
  109. package/dist/runtime/services/secrets.service.cjs.map +1 -0
  110. package/dist/runtime/services/secrets.service.d.cts +16 -0
  111. package/dist/runtime/services/secrets.service.d.cts.map +1 -0
  112. package/dist/runtime/services/secrets.service.d.mts +16 -0
  113. package/dist/runtime/services/secrets.service.d.mts.map +1 -0
  114. package/dist/runtime/services/secrets.service.mjs +48 -0
  115. package/dist/runtime/services/secrets.service.mjs.map +1 -0
  116. package/dist/runtime/validation.cjs +18 -0
  117. package/dist/runtime/validation.cjs.map +1 -0
  118. package/dist/runtime/validation.mjs +17 -0
  119. package/dist/runtime/validation.mjs.map +1 -0
  120. package/dist/testing/index.cjs +2 -4
  121. package/dist/testing/index.cjs.map +1 -1
  122. package/dist/testing/index.d.cts +4 -4
  123. package/dist/testing/index.d.mts +4 -4
  124. package/dist/testing/index.mjs +1 -3
  125. package/dist/testing/index.mjs.map +1 -1
  126. package/dist/types.cjs +0 -0
  127. package/dist/types.d.cts +261 -0
  128. package/dist/types.d.cts.map +1 -0
  129. package/dist/types.d.mts +261 -0
  130. package/dist/types.d.mts.map +1 -0
  131. package/dist/types.mjs +1 -0
  132. package/dist/zod-core.cjs +9 -0
  133. package/dist/zod-core.d.cts +1 -0
  134. package/dist/zod-core.d.mts +1 -0
  135. package/dist/zod-core.mjs +3 -0
  136. package/dist/zod.cjs +13 -1
  137. package/dist/zod.cjs.map +1 -0
  138. package/dist/zod.d.cts +8 -2
  139. package/dist/zod.d.cts.map +1 -0
  140. package/dist/zod.d.mts +8 -2
  141. package/dist/zod.d.mts.map +1 -0
  142. package/dist/zod.mjs +9 -2
  143. package/dist/zod.mjs.map +1 -0
  144. package/package.json +17 -2
  145. package/dist/build/rspack/index.cjs.map +0 -1
  146. package/dist/build/rspack/index.d.cts.map +0 -1
  147. package/dist/build/rspack/index.d.mts.map +0 -1
  148. package/dist/build/rspack/index.mjs.map +0 -1
  149. package/dist/errors-9sNpYLv5.d.mts +0 -75
  150. package/dist/errors-9sNpYLv5.d.mts.map +0 -1
  151. package/dist/errors-CVnoPl9v.cjs +0 -68
  152. package/dist/errors-CVnoPl9v.cjs.map +0 -1
  153. package/dist/errors-D7keKf7a.mjs +0 -63
  154. package/dist/errors-D7keKf7a.mjs.map +0 -1
  155. package/dist/errors-DKPPPYYT.d.cts +0 -75
  156. package/dist/errors-DKPPPYYT.d.cts.map +0 -1
  157. package/dist/fetch-8DauUFDh.mjs +0 -335
  158. package/dist/fetch-8DauUFDh.mjs.map +0 -1
  159. package/dist/fetch-CrBvwsZ4.cjs +0 -336
  160. package/dist/fetch-CrBvwsZ4.cjs.map +0 -1
  161. package/dist/index-Bu2wtZrA.d.mts +0 -463
  162. package/dist/index-Bu2wtZrA.d.mts.map +0 -1
  163. package/dist/index-DtTqwV4f.d.cts +0 -462
  164. package/dist/index-DtTqwV4f.d.cts.map +0 -1
  165. package/dist/index.cjs.map +0 -1
  166. package/dist/index.mjs.map +0 -1
  167. package/dist/normalize-BW7kk8Lk.d.cts +0 -21
  168. package/dist/normalize-BW7kk8Lk.d.cts.map +0 -1
  169. package/dist/normalize-D4Qh0wVk.cjs +0 -28
  170. package/dist/normalize-D4Qh0wVk.cjs.map +0 -1
  171. package/dist/normalize-D7nae0Hn.mjs +0 -22
  172. package/dist/normalize-D7nae0Hn.mjs.map +0 -1
  173. package/dist/normalize-eB_j86fm.d.mts +0 -21
  174. package/dist/normalize-eB_j86fm.d.mts.map +0 -1
  175. package/dist/package-CaRYwbRi.mjs.map +0 -1
  176. package/dist/package-DyTuSutr.cjs.map +0 -1
  177. package/dist/plugins-C6MGKdD-.mjs +0 -790
  178. package/dist/plugins-C6MGKdD-.mjs.map +0 -1
  179. package/dist/plugins-DNaNtkG7.cjs +0 -791
  180. package/dist/plugins-DNaNtkG7.cjs.map +0 -1
  181. package/dist/runtime-BNcFgWDG.cjs +0 -558
  182. package/dist/runtime-BNcFgWDG.cjs.map +0 -1
  183. package/dist/runtime-CAWcnrAk.mjs +0 -547
  184. package/dist/runtime-CAWcnrAk.mjs.map +0 -1
  185. package/dist/standard-CkH8zNkx.mjs +0 -584
  186. package/dist/standard-CkH8zNkx.mjs.map +0 -1
  187. package/dist/standard-v75BC6Z5.cjs +0 -685
  188. package/dist/standard-v75BC6Z5.cjs.map +0 -1
  189. package/dist/zod-A7Pti5IV.d.cts +0 -4
  190. package/dist/zod-A7Pti5IV.d.cts.map +0 -1
  191. package/dist/zod-BVo51kgJ.mjs +0 -10
  192. package/dist/zod-BVo51kgJ.mjs.map +0 -1
  193. package/dist/zod-DYghWCz1.cjs +0 -14
  194. package/dist/zod-DYghWCz1.cjs.map +0 -1
  195. package/dist/zod-Zw8dlP3j.d.mts +0 -4
  196. package/dist/zod-Zw8dlP3j.d.mts.map +0 -1
@@ -0,0 +1,41 @@
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 isRetryableORPCCode = (code) => {
9
+ switch (code) {
10
+ case "TOO_MANY_REQUESTS":
11
+ case "SERVICE_UNAVAILABLE":
12
+ case "BAD_GATEWAY":
13
+ case "GATEWAY_TIMEOUT":
14
+ case "TIMEOUT": return true;
15
+ default: return false;
16
+ }
17
+ };
18
+ const wrapORPCError = (orpcError, pluginId, procedureName, operation) => {
19
+ return new PluginRuntimeError({
20
+ pluginId,
21
+ operation,
22
+ procedureName,
23
+ retryable: isRetryableORPCCode(orpcError.code),
24
+ cause: orpcError
25
+ });
26
+ };
27
+ const toPluginRuntimeError = (error, pluginId, procedureName, operation, defaultRetryable = false) => {
28
+ if (error instanceof ORPCError) return wrapORPCError(error, pluginId, procedureName, operation);
29
+ if (error instanceof PluginRuntimeError) return error;
30
+ return new PluginRuntimeError({
31
+ pluginId,
32
+ operation,
33
+ procedureName,
34
+ retryable: defaultRetryable,
35
+ cause: error instanceof Error ? error : new Error(String(error))
36
+ });
37
+ };
38
+
39
+ //#endregion
40
+ export { ModuleFederationError, PluginRuntimeError, ValidationError, toPluginRuntimeError };
41
+ //# sourceMappingURL=errors.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.mjs","names":[],"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\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; // Already converted\n\t}\n\n\treturn new PluginRuntimeError({\n\t\tpluginId,\n\t\toperation,\n\t\tprocedureName,\n\t\tretryable: defaultRetryable,\n\t\tcause: error instanceof Error ? error : new Error(String(error))\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;AAGH,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;AAGR,QAAO,IAAI,mBAAmB;EAC7B;EACA;EACA;EACA,WAAW;EACX,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;EAChE,CAAC"}
@@ -1,6 +1,158 @@
1
- const require_runtime = require('../runtime-BNcFgWDG.cjs');
2
- require('../normalize-D4Qh0wVk.cjs');
3
- require('../package-DyTuSutr.cjs');
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
- exports.PluginRuntime = require_runtime.PluginRuntime;
6
- exports.createPluginRuntime = require_runtime.createPluginRuntime;
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":"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"}
@@ -1,5 +1,43 @@
1
- import "../zod-A7Pti5IV.cjs";
2
- import "../errors-DKPPPYYT.cjs";
3
- import { n as createPluginRuntime, t as PluginRuntime } from "../index-DtTqwV4f.cjs";
4
- import "../normalize-BW7kk8Lk.cjs";
5
- export { PluginRuntime, createPluginRuntime };
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"}
@@ -1,5 +1,43 @@
1
- import "../zod-Zw8dlP3j.mjs";
2
- import "../errors-9sNpYLv5.mjs";
3
- import { n as createPluginRuntime, t as PluginRuntime } from "../index-Bu2wtZrA.mjs";
4
- import "../normalize-eB_j86fm.mjs";
5
- export { PluginRuntime, createPluginRuntime };
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"}
@@ -1,5 +1,156 @@
1
- import { n as createPluginRuntime, t as PluginRuntime } from "../runtime-CAWcnrAk.mjs";
2
- import "../normalize-D7nae0Hn.mjs";
3
- import "../package-CaRYwbRi.mjs";
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
- export { PluginRuntime, createPluginRuntime };
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["runtime: ManagedRuntime.ManagedRuntime<PluginService, never>","registry: PluginRegistry","pluginMap: Record<string, AnyPluginConstructor>","normalized: Record<string, PluginRegistryEntry>"],"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":"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"}