every-plugin 2.2.6 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/dist/build/rspack/dev-server-middleware.cjs +1 -2
  2. package/dist/build/rspack/dev-server-middleware.cjs.map +1 -1
  3. package/dist/build/rspack/dev-server-middleware.mjs +1 -2
  4. package/dist/build/rspack/dev-server-middleware.mjs.map +1 -1
  5. package/dist/build/rspack/plugin.cjs +20 -0
  6. package/dist/build/rspack/plugin.cjs.map +1 -1
  7. package/dist/build/rspack/plugin.d.cts +5 -0
  8. package/dist/build/rspack/plugin.d.cts.map +1 -1
  9. package/dist/build/rspack/plugin.d.mts +5 -0
  10. package/dist/build/rspack/plugin.d.mts.map +1 -1
  11. package/dist/build/rspack/plugin.mjs +20 -0
  12. package/dist/build/rspack/plugin.mjs.map +1 -1
  13. package/dist/index.d.cts +2 -2
  14. package/dist/index.d.mts +2 -2
  15. package/dist/plugin.cjs +2 -1
  16. package/dist/plugin.cjs.map +1 -1
  17. package/dist/plugin.d.cts.map +1 -1
  18. package/dist/plugin.d.mts.map +1 -1
  19. package/dist/plugin.mjs +2 -1
  20. package/dist/plugin.mjs.map +1 -1
  21. package/dist/runtime/index.cjs +2 -2
  22. package/dist/runtime/index.cjs.map +1 -1
  23. package/dist/runtime/index.d.cts.map +1 -1
  24. package/dist/runtime/index.d.mts.map +1 -1
  25. package/dist/runtime/index.mjs +2 -2
  26. package/dist/runtime/index.mjs.map +1 -1
  27. package/dist/runtime/mf-config.cjs +12 -4
  28. package/dist/runtime/mf-config.cjs.map +1 -1
  29. package/dist/runtime/mf-config.d.cts +2 -2
  30. package/dist/runtime/mf-config.d.cts.map +1 -1
  31. package/dist/runtime/mf-config.d.mts +2 -2
  32. package/dist/runtime/mf-config.d.mts.map +1 -1
  33. package/dist/runtime/mf-config.mjs +12 -4
  34. package/dist/runtime/mf-config.mjs.map +1 -1
  35. package/dist/runtime/services/plugin-lifecycle.service.cjs +5 -2
  36. package/dist/runtime/services/plugin-lifecycle.service.cjs.map +1 -1
  37. package/dist/runtime/services/plugin-lifecycle.service.mjs +6 -3
  38. package/dist/runtime/services/plugin-lifecycle.service.mjs.map +1 -1
  39. package/dist/runtime/services/plugin.service.cjs +1 -1
  40. package/dist/runtime/services/plugin.service.cjs.map +1 -1
  41. package/dist/runtime/services/plugin.service.d.cts.map +1 -1
  42. package/dist/runtime/services/plugin.service.d.mts.map +1 -1
  43. package/dist/runtime/services/plugin.service.mjs +1 -1
  44. package/dist/runtime/services/plugin.service.mjs.map +1 -1
  45. package/package.json +1 -1
  46. package/src/build/rspack/dev-server-middleware.ts +1 -6
  47. package/src/build/rspack/plugin.ts +38 -1
  48. package/src/index.ts +1 -0
  49. package/src/plugin.ts +8 -1
  50. package/src/runtime/index.ts +10 -2
  51. package/src/runtime/mf-config.ts +11 -2
  52. package/src/runtime/services/plugin-lifecycle.service.ts +18 -23
  53. package/src/runtime/services/plugin.service.ts +7 -4
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["Hash","Effect","PluginRuntimeError","effect","Exit","Cause","Option","PluginService","ManagedRuntime"],"sources":["../../src/runtime/index.ts"],"sourcesContent":["import { createRouterClient } from \"@orpc/server\";\nimport { Cause, Effect, Exit, Hash, ManagedRuntime, Option } from \"effect\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InferRegistryFromEntries,\n InitializedPlugin,\n LoadedPlugin,\n PluginConfigInput,\n PluginInstance,\n PluginRegistry,\n PluginRegistryEntry,\n PluginRouterType,\n PluginRuntimeConfig,\n RegisteredPlugin,\n RegisteredPlugins,\n UsePluginResult,\n} from \"../types\";\nimport { PluginRuntimeError } from \"./errors\";\nimport { PluginService } from \"./services/plugin.service\";\n\nexport class PluginRuntime<R = RegisteredPlugins> {\n readonly __registryType?: R;\n\n private pluginCache = new Map<\n string,\n Effect.Effect<InitializedPlugin<AnyPlugin>, PluginRuntimeError>\n >();\n\n constructor(\n private runtime: ManagedRuntime.ManagedRuntime<PluginService, never>,\n private registry: PluginRegistry,\n ) {}\n\n private generateCacheKey(pluginId: string, config: unknown): string {\n const configHash = Hash.structure(config as object).toString();\n return `${pluginId}:${configHash}`;\n }\n\n private validatePluginId(pluginId: string): Effect.Effect<string, PluginRuntimeError> {\n if (!(pluginId in this.registry)) {\n return Effect.fail(\n new PluginRuntimeError({\n pluginId: String(pluginId),\n operation: \"validate-plugin-id\",\n cause: new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),\n retryable: false,\n }),\n );\n }\n return Effect.succeed(String(pluginId));\n }\n\n private async runPromise<A, E>(effect: Effect.Effect<A, E, PluginService>): Promise<A> {\n const exit = await this.runtime.runPromiseExit(effect);\n\n if (Exit.isFailure(exit)) {\n const error = Cause.failureOption(exit.cause);\n if (Option.isSome(error)) {\n throw error.value;\n }\n throw Cause.squash(exit.cause);\n }\n\n return exit.value;\n }\n\n async usePlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n plugins?: Record<string, unknown>,\n ): Promise<UsePluginResult<K, R>> {\n const cacheKey = this.generateCacheKey(pluginId, { ...config, __plugins: plugins ?? {} });\n\n let cachedPlugin = this.pluginCache.get(cacheKey);\n if (!cachedPlugin) {\n const operation = Effect.gen(this, function* () {\n const pluginService = yield* PluginService;\n const validatedId = yield* this.validatePluginId(pluginId);\n\n // Load → Instantiate → Initialize\n const ctor = yield* pluginService.loadPlugin(validatedId);\n const instance = yield* pluginService.instantiatePlugin(pluginId, ctor);\n const initialized = yield* pluginService.initializePlugin(instance, config, plugins);\n\n return initialized;\n }).pipe(Effect.provide(this.runtime));\n\n cachedPlugin = Effect.cached(operation).pipe(Effect.flatten);\n this.pluginCache.set(cacheKey, cachedPlugin);\n }\n\n const initialized = await this.runPromise(cachedPlugin);\n\n // Create client factory that accepts request context\n const createClient = (context?: any) => {\n const router = initialized.plugin.createRouter(initialized.context);\n return createRouterClient(router, { context: context ?? {} });\n };\n\n return {\n createClient: createClient as any,\n router: initialized.plugin.createRouter(initialized.context) as PluginRouterType<R[K]>,\n metadata: initialized.metadata,\n initialized: initialized as InitializedPlugin<RegisteredPlugin<K, R>>,\n } as UsePluginResult<K, R>;\n }\n\n async loadPlugin<K extends keyof R & string>(\n pluginId: K,\n ): Promise<LoadedPlugin<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.loadPlugin(pluginId);\n });\n return this.runPromise(effect) as Promise<LoadedPlugin<RegisteredPlugin<K, R>>>;\n }\n\n async instantiatePlugin<K extends keyof R & string>(\n pluginId: K,\n loadedPlugin: LoadedPlugin<RegisteredPlugin<K, R>>,\n ): Promise<PluginInstance<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.instantiatePlugin(pluginId, loadedPlugin);\n });\n return this.runPromise(effect) as Promise<PluginInstance<RegisteredPlugin<K, R>>>;\n }\n\n async initializePlugin<T extends AnyPlugin>(\n instance: PluginInstance<T>,\n config: any,\n plugins?: Record<string, unknown>,\n ): Promise<InitializedPlugin<T>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.initializePlugin(instance, config, plugins);\n });\n return this.runPromise(effect);\n }\n\n async shutdown(): Promise<void> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n yield* pluginService.cleanup();\n });\n return this.runPromise(effect);\n }\n\n async evictPlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n ): Promise<void> {\n const cacheKey = this.generateCacheKey(pluginId, config);\n\n const effect = Effect.gen(this, function* () {\n const pluginService = yield* PluginService;\n const cachedPlugin = this.pluginCache.get(cacheKey);\n\n if (cachedPlugin) {\n this.pluginCache.delete(cacheKey);\n\n const pluginResult = yield* cachedPlugin.pipe(Effect.catchAll(() => Effect.succeed(null)));\n\n if (pluginResult) {\n yield* pluginService\n .shutdownPlugin(pluginResult)\n .pipe(Effect.catchAll(() => Effect.void));\n }\n }\n }).pipe(Effect.catchAll(() => Effect.void));\n\n return this.runPromise(effect);\n }\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 if (!url) return url;\n if (url.endsWith(\".js\") || url.endsWith(\".json\")) return url;\n return `${url.endsWith(\"/\") ? url.slice(0, -1) : url}/remoteEntry.js`;\n}\n\n/**\n * Extract plugin map (module constructors) from registry entries\n */\nfunction extractPluginMap(\n registry: Record<string, PluginRegistryEntry>,\n): Record<string, AnyPluginConstructor> {\n const pluginMap: Record<string, AnyPluginConstructor> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry && entry.module) {\n pluginMap[pluginId] = entry.module;\n }\n }\n\n return pluginMap;\n}\n\n/**\n * Normalize registry entries - ensure remote URLs are properly formatted\n */\nfunction normalizeRegistry(registry: Record<string, PluginRegistryEntry>): PluginRegistry {\n const normalized: Record<string, PluginRegistryEntry> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry) {\n normalized[pluginId] = {\n ...entry,\n remote: entry.remote ? normalizeRemoteUrl(entry.remote) : undefined,\n };\n } else {\n normalized[pluginId] = {\n ...entry,\n remote: normalizeRemoteUrl(entry.remote),\n };\n }\n }\n\n return 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 { router } = await runtime.usePlugin(\"telegram\", config);\n * ```\n */\nexport function createPluginRuntime<TRegistry extends Record<string, PluginRegistryEntry>>(\n config: PluginRuntimeConfig<TRegistry>,\n): PluginRuntime<InferRegistryFromEntries<TRegistry>> {\n const secrets = config.secrets || {};\n const normalizedRegistry = normalizeRegistry(config.registry);\n const pluginMap = extractPluginMap(config.registry);\n\n const layer = PluginService.Live(normalizedRegistry, secrets, pluginMap);\n const runtime = ManagedRuntime.make(layer);\n\n return new PluginRuntime(runtime, normalizedRegistry) as PluginRuntime<\n InferRegistryFromEntries<TRegistry>\n >;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["Hash","Effect","PluginRuntimeError","effect","Exit","Cause","Option","PluginService","ManagedRuntime"],"sources":["../../src/runtime/index.ts"],"sourcesContent":["import { createRouterClient } from \"@orpc/server\";\nimport { Cause, Effect, Exit, Hash, ManagedRuntime, Option } from \"effect\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InferRegistryFromEntries,\n InitializedPlugin,\n LoadedPlugin,\n PluginConfigInput,\n PluginInstance,\n PluginRegistry,\n PluginRegistryEntry,\n PluginRouterType,\n PluginRuntimeConfig,\n RegisteredPlugin,\n RegisteredPlugins,\n UsePluginResult,\n} from \"../types\";\nimport { PluginRuntimeError } from \"./errors\";\nimport { PluginService } from \"./services/plugin.service\";\n\nexport class PluginRuntime<R = RegisteredPlugins> {\n readonly __registryType?: R;\n\n private pluginCache = new Map<\n string,\n Effect.Effect<InitializedPlugin<AnyPlugin>, PluginRuntimeError>\n >();\n\n constructor(\n private runtime: ManagedRuntime.ManagedRuntime<PluginService, never>,\n private registry: PluginRegistry,\n ) {}\n\n private generateCacheKey(pluginId: string, config: unknown): string {\n const configHash = Hash.structure(config as object).toString();\n return `${pluginId}:${configHash}`;\n }\n\n private validatePluginId(pluginId: string): Effect.Effect<string, PluginRuntimeError> {\n if (!(pluginId in this.registry)) {\n return Effect.fail(\n new PluginRuntimeError({\n pluginId: String(pluginId),\n operation: \"validate-plugin-id\",\n cause: new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),\n retryable: false,\n }),\n );\n }\n return Effect.succeed(String(pluginId));\n }\n\n private async runPromise<A, E>(effect: Effect.Effect<A, E, PluginService>): Promise<A> {\n const exit = await this.runtime.runPromiseExit(effect);\n\n if (Exit.isFailure(exit)) {\n const error = Cause.failureOption(exit.cause);\n if (Option.isSome(error)) {\n throw error.value;\n }\n throw Cause.squash(exit.cause);\n }\n\n return exit.value;\n }\n\n async usePlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n plugins?: Record<string, unknown>,\n ): Promise<UsePluginResult<K, R>> {\n const cacheKey = this.generateCacheKey(pluginId, { ...config, __plugins: plugins ?? {} });\n\n let cachedPlugin = this.pluginCache.get(cacheKey);\n if (!cachedPlugin) {\n const operation = Effect.gen(this, function* () {\n const pluginService = yield* PluginService;\n const validatedId = yield* this.validatePluginId(pluginId);\n\n // Load → Instantiate → Initialize\n const ctor = yield* pluginService.loadPlugin(validatedId);\n const instance = yield* pluginService.instantiatePlugin(pluginId, ctor);\n const initialized = yield* pluginService.initializePlugin(instance, config, plugins);\n\n return initialized;\n }).pipe(Effect.provide(this.runtime));\n\n cachedPlugin = Effect.cached(operation).pipe(Effect.flatten);\n this.pluginCache.set(cacheKey, cachedPlugin);\n }\n\n const initialized = await this.runPromise(cachedPlugin);\n\n // Create client factory that accepts request context\n const createClient = (context?: any) => {\n const router = initialized.plugin.createRouter(initialized.context);\n return createRouterClient(router, { context: context ?? {} });\n };\n\n return {\n createClient: createClient as any,\n router: initialized.plugin.createRouter(initialized.context) as PluginRouterType<R[K]>,\n metadata: initialized.metadata,\n initialized: initialized as InitializedPlugin<RegisteredPlugin<K, R>>,\n } as UsePluginResult<K, R>;\n }\n\n async loadPlugin<K extends keyof R & string>(\n pluginId: K,\n ): Promise<LoadedPlugin<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.loadPlugin(pluginId);\n });\n return this.runPromise(effect) as Promise<LoadedPlugin<RegisteredPlugin<K, R>>>;\n }\n\n async instantiatePlugin<K extends keyof R & string>(\n pluginId: K,\n loadedPlugin: LoadedPlugin<RegisteredPlugin<K, R>>,\n ): Promise<PluginInstance<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.instantiatePlugin(pluginId, loadedPlugin);\n });\n return this.runPromise(effect) as Promise<PluginInstance<RegisteredPlugin<K, R>>>;\n }\n\n async initializePlugin<T extends AnyPlugin>(\n instance: PluginInstance<T>,\n config: any,\n plugins?: Record<string, unknown>,\n ): Promise<InitializedPlugin<T>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.initializePlugin(instance, config, plugins);\n });\n return this.runPromise(effect);\n }\n\n async shutdown(): Promise<void> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n yield* pluginService.cleanup();\n });\n return this.runPromise(effect);\n }\n\n async evictPlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n ): Promise<void> {\n const cacheKey = this.generateCacheKey(pluginId, config);\n\n const effect = Effect.gen(this, function* () {\n const pluginService = yield* PluginService;\n const cachedPlugin = this.pluginCache.get(cacheKey);\n\n if (cachedPlugin) {\n this.pluginCache.delete(cacheKey);\n\n const pluginResult = yield* cachedPlugin.pipe(Effect.catchAll(() => Effect.succeed(null)));\n\n if (pluginResult) {\n yield* pluginService\n .shutdownPlugin(pluginResult)\n .pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(`Failed to shutdown evicted plugin ${pluginId}`, error),\n ),\n );\n }\n }\n }).pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(`Plugin eviction failed for ${pluginId}`, error),\n ),\n );\n\n return this.runPromise(effect);\n }\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 if (!url) return url;\n if (url.endsWith(\".js\") || url.endsWith(\".json\")) return url;\n return `${url.endsWith(\"/\") ? url.slice(0, -1) : url}/remoteEntry.js`;\n}\n\n/**\n * Extract plugin map (module constructors) from registry entries\n */\nfunction extractPluginMap(\n registry: Record<string, PluginRegistryEntry>,\n): Record<string, AnyPluginConstructor> {\n const pluginMap: Record<string, AnyPluginConstructor> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry && entry.module) {\n pluginMap[pluginId] = entry.module;\n }\n }\n\n return pluginMap;\n}\n\n/**\n * Normalize registry entries - ensure remote URLs are properly formatted\n */\nfunction normalizeRegistry(registry: Record<string, PluginRegistryEntry>): PluginRegistry {\n const normalized: Record<string, PluginRegistryEntry> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry) {\n normalized[pluginId] = {\n ...entry,\n remote: entry.remote ? normalizeRemoteUrl(entry.remote) : undefined,\n };\n } else {\n normalized[pluginId] = {\n ...entry,\n remote: normalizeRemoteUrl(entry.remote),\n };\n }\n }\n\n return 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 { router } = await runtime.usePlugin(\"telegram\", config);\n * ```\n */\nexport function createPluginRuntime<TRegistry extends Record<string, PluginRegistryEntry>>(\n config: PluginRuntimeConfig<TRegistry>,\n): PluginRuntime<InferRegistryFromEntries<TRegistry>> {\n const secrets = config.secrets || {};\n const normalizedRegistry = normalizeRegistry(config.registry);\n const pluginMap = extractPluginMap(config.registry);\n\n const layer = PluginService.Live(normalizedRegistry, secrets, pluginMap);\n const runtime = ManagedRuntime.make(layer);\n\n return new PluginRuntime(runtime, normalizedRegistry) as PluginRuntime<\n InferRegistryFromEntries<TRegistry>\n >;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/runtime/index.ts"],"mappings":";;;;;cAqBa,aAAA,KAAkB,iBAAA;EAAA,QASnB,OAAA;EAAA,QACA,QAAA;EAAA,SATD,cAAA,GAAiB,CAAA;EAAA,QAElB,WAAA;cAME,OAAA,EAAS,cAAA,CAAe,cAAA,CAAe,aAAA,UACvC,QAAA,EAAU,cAAA;EAAA,QAGZ,gBAAA;EAAA,QAKA,gBAAA;EAAA,QAcM,UAAA;EAcR,SAAA,iBAA0B,CAAA,UAAA,CAC9B,QAAA,EAAU,CAAA,EACV,MAAA,EAAQ,iBAAA,CAAkB,CAAA,CAAE,CAAA,IAC5B,OAAA,GAAU,MAAA,oBACT,OAAA,CAAQ,eAAA,CAAgB,CAAA,EAAG,CAAA;EAqCxB,UAAA,iBAA2B,CAAA,UAAA,CAC/B,QAAA,EAAU,CAAA,GACT,OAAA,CAAQ,YAAA,CAAa,gBAAA,CAAiB,CAAA,EAAG,CAAA;EAQtC,iBAAA,iBAAkC,CAAA,UAAA,CACtC,QAAA,EAAU,CAAA,EACV,YAAA,EAAc,YAAA,CAAa,gBAAA,CAAiB,CAAA,EAAG,CAAA,KAC9C,OAAA,CAAQ,cAAA,CAAe,gBAAA,CAAiB,CAAA,EAAG,CAAA;EAQxC,gBAAA,WAA2B,SAAA,CAAA,CAC/B,QAAA,EAAU,cAAA,CAAe,CAAA,GACzB,MAAA,OACA,OAAA,GAAU,MAAA,oBACT,OAAA,CAAQ,iBAAA,CAAkB,CAAA;EAQvB,QAAA,CAAA,GAAY,OAAA;EAQZ,WAAA,iBAA4B,CAAA,UAAA,CAChC,QAAA,EAAU,CAAA,EACV,MAAA,EAAQ,iBAAA,CAAkB,CAAA,CAAE,CAAA,KAC3B,OAAA;AAAA;;;;;;;;;;;;;;;;;;;iBA4FW,mBAAA,mBAAsC,MAAA,SAAe,mBAAA,EAAA,CACnE,MAAA,EAAQ,mBAAA,CAAoB,SAAA,IAC3B,aAAA,CAAc,wBAAA,CAAyB,SAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/runtime/index.ts"],"mappings":";;;;;cAqBa,aAAA,KAAkB,iBAAA;EAAA,QASnB,OAAA;EAAA,QACA,QAAA;EAAA,SATD,cAAA,GAAiB,CAAA;EAAA,QAElB,WAAA;cAME,OAAA,EAAS,cAAA,CAAe,cAAA,CAAe,aAAA,UACvC,QAAA,EAAU,cAAA;EAAA,QAGZ,gBAAA;EAAA,QAKA,gBAAA;EAAA,QAcM,UAAA;EAcR,SAAA,iBAA0B,CAAA,UAAA,CAC9B,QAAA,EAAU,CAAA,EACV,MAAA,EAAQ,iBAAA,CAAkB,CAAA,CAAE,CAAA,IAC5B,OAAA,GAAU,MAAA,oBACT,OAAA,CAAQ,eAAA,CAAgB,CAAA,EAAG,CAAA;EAqCxB,UAAA,iBAA2B,CAAA,UAAA,CAC/B,QAAA,EAAU,CAAA,GACT,OAAA,CAAQ,YAAA,CAAa,gBAAA,CAAiB,CAAA,EAAG,CAAA;EAQtC,iBAAA,iBAAkC,CAAA,UAAA,CACtC,QAAA,EAAU,CAAA,EACV,YAAA,EAAc,YAAA,CAAa,gBAAA,CAAiB,CAAA,EAAG,CAAA,KAC9C,OAAA,CAAQ,cAAA,CAAe,gBAAA,CAAiB,CAAA,EAAG,CAAA;EAQxC,gBAAA,WAA2B,SAAA,CAAA,CAC/B,QAAA,EAAU,cAAA,CAAe,CAAA,GACzB,MAAA,OACA,OAAA,GAAU,MAAA,oBACT,OAAA,CAAQ,iBAAA,CAAkB,CAAA;EAQvB,QAAA,CAAA,GAAY,OAAA;EAQZ,WAAA,iBAA4B,CAAA,UAAA,CAChC,QAAA,EAAU,CAAA,EACV,MAAA,EAAQ,iBAAA,CAAkB,CAAA,CAAE,CAAA,KAC3B,OAAA;AAAA;;;;;;;;;;;;;;;;;;;iBAoGW,mBAAA,mBAAsC,MAAA,SAAe,mBAAA,EAAA,CACnE,MAAA,EAAQ,mBAAA,CAAoB,SAAA,IAC3B,aAAA,CAAc,wBAAA,CAAyB,SAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/runtime/index.ts"],"mappings":";;;;;cAqBa,aAAA,KAAkB,iBAAA;EAAA,QASnB,OAAA;EAAA,QACA,QAAA;EAAA,SATD,cAAA,GAAiB,CAAA;EAAA,QAElB,WAAA;cAME,OAAA,EAAS,cAAA,CAAe,cAAA,CAAe,aAAA,UACvC,QAAA,EAAU,cAAA;EAAA,QAGZ,gBAAA;EAAA,QAKA,gBAAA;EAAA,QAcM,UAAA;EAcR,SAAA,iBAA0B,CAAA,UAAA,CAC9B,QAAA,EAAU,CAAA,EACV,MAAA,EAAQ,iBAAA,CAAkB,CAAA,CAAE,CAAA,IAC5B,OAAA,GAAU,MAAA,oBACT,OAAA,CAAQ,eAAA,CAAgB,CAAA,EAAG,CAAA;EAqCxB,UAAA,iBAA2B,CAAA,UAAA,CAC/B,QAAA,EAAU,CAAA,GACT,OAAA,CAAQ,YAAA,CAAa,gBAAA,CAAiB,CAAA,EAAG,CAAA;EAQtC,iBAAA,iBAAkC,CAAA,UAAA,CACtC,QAAA,EAAU,CAAA,EACV,YAAA,EAAc,YAAA,CAAa,gBAAA,CAAiB,CAAA,EAAG,CAAA,KAC9C,OAAA,CAAQ,cAAA,CAAe,gBAAA,CAAiB,CAAA,EAAG,CAAA;EAQxC,gBAAA,WAA2B,SAAA,CAAA,CAC/B,QAAA,EAAU,cAAA,CAAe,CAAA,GACzB,MAAA,OACA,OAAA,GAAU,MAAA,oBACT,OAAA,CAAQ,iBAAA,CAAkB,CAAA;EAQvB,QAAA,CAAA,GAAY,OAAA;EAQZ,WAAA,iBAA4B,CAAA,UAAA,CAChC,QAAA,EAAU,CAAA,EACV,MAAA,EAAQ,iBAAA,CAAkB,CAAA,CAAE,CAAA,KAC3B,OAAA;AAAA;;;;;;;;;;;;;;;;;;;iBA4FW,mBAAA,mBAAsC,MAAA,SAAe,mBAAA,EAAA,CACnE,MAAA,EAAQ,mBAAA,CAAoB,SAAA,IAC3B,aAAA,CAAc,wBAAA,CAAyB,SAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/runtime/index.ts"],"mappings":";;;;;cAqBa,aAAA,KAAkB,iBAAA;EAAA,QASnB,OAAA;EAAA,QACA,QAAA;EAAA,SATD,cAAA,GAAiB,CAAA;EAAA,QAElB,WAAA;cAME,OAAA,EAAS,cAAA,CAAe,cAAA,CAAe,aAAA,UACvC,QAAA,EAAU,cAAA;EAAA,QAGZ,gBAAA;EAAA,QAKA,gBAAA;EAAA,QAcM,UAAA;EAcR,SAAA,iBAA0B,CAAA,UAAA,CAC9B,QAAA,EAAU,CAAA,EACV,MAAA,EAAQ,iBAAA,CAAkB,CAAA,CAAE,CAAA,IAC5B,OAAA,GAAU,MAAA,oBACT,OAAA,CAAQ,eAAA,CAAgB,CAAA,EAAG,CAAA;EAqCxB,UAAA,iBAA2B,CAAA,UAAA,CAC/B,QAAA,EAAU,CAAA,GACT,OAAA,CAAQ,YAAA,CAAa,gBAAA,CAAiB,CAAA,EAAG,CAAA;EAQtC,iBAAA,iBAAkC,CAAA,UAAA,CACtC,QAAA,EAAU,CAAA,EACV,YAAA,EAAc,YAAA,CAAa,gBAAA,CAAiB,CAAA,EAAG,CAAA,KAC9C,OAAA,CAAQ,cAAA,CAAe,gBAAA,CAAiB,CAAA,EAAG,CAAA;EAQxC,gBAAA,WAA2B,SAAA,CAAA,CAC/B,QAAA,EAAU,cAAA,CAAe,CAAA,GACzB,MAAA,OACA,OAAA,GAAU,MAAA,oBACT,OAAA,CAAQ,iBAAA,CAAkB,CAAA;EAQvB,QAAA,CAAA,GAAY,OAAA;EAQZ,WAAA,iBAA4B,CAAA,UAAA,CAChC,QAAA,EAAU,CAAA,EACV,MAAA,EAAQ,iBAAA,CAAkB,CAAA,CAAE,CAAA,KAC3B,OAAA;AAAA;;;;;;;;;;;;;;;;;;;iBAoGW,mBAAA,mBAAsC,MAAA,SAAe,mBAAA,EAAA,CACnE,MAAA,EAAQ,mBAAA,CAAoB,SAAA,IAC3B,aAAA,CAAc,wBAAA,CAAyB,SAAA"}
@@ -92,9 +92,9 @@ var PluginRuntime = class {
92
92
  if (cachedPlugin) {
93
93
  this.pluginCache.delete(cacheKey);
94
94
  const pluginResult = yield* cachedPlugin.pipe(Effect.catchAll(() => Effect.succeed(null)));
95
- if (pluginResult) yield* pluginService.shutdownPlugin(pluginResult).pipe(Effect.catchAll(() => Effect.void));
95
+ if (pluginResult) yield* pluginService.shutdownPlugin(pluginResult).pipe(Effect.catchAll((error) => Effect.logWarning(`Failed to shutdown evicted plugin ${pluginId}`, error)));
96
96
  }
97
- }).pipe(Effect.catchAll(() => Effect.void));
97
+ }).pipe(Effect.catchAll((error) => Effect.logWarning(`Plugin eviction failed for ${pluginId}`, error)));
98
98
  return this.runPromise(effect);
99
99
  }
100
100
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/runtime/index.ts"],"sourcesContent":["import { createRouterClient } from \"@orpc/server\";\nimport { Cause, Effect, Exit, Hash, ManagedRuntime, Option } from \"effect\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InferRegistryFromEntries,\n InitializedPlugin,\n LoadedPlugin,\n PluginConfigInput,\n PluginInstance,\n PluginRegistry,\n PluginRegistryEntry,\n PluginRouterType,\n PluginRuntimeConfig,\n RegisteredPlugin,\n RegisteredPlugins,\n UsePluginResult,\n} from \"../types\";\nimport { PluginRuntimeError } from \"./errors\";\nimport { PluginService } from \"./services/plugin.service\";\n\nexport class PluginRuntime<R = RegisteredPlugins> {\n readonly __registryType?: R;\n\n private pluginCache = new Map<\n string,\n Effect.Effect<InitializedPlugin<AnyPlugin>, PluginRuntimeError>\n >();\n\n constructor(\n private runtime: ManagedRuntime.ManagedRuntime<PluginService, never>,\n private registry: PluginRegistry,\n ) {}\n\n private generateCacheKey(pluginId: string, config: unknown): string {\n const configHash = Hash.structure(config as object).toString();\n return `${pluginId}:${configHash}`;\n }\n\n private validatePluginId(pluginId: string): Effect.Effect<string, PluginRuntimeError> {\n if (!(pluginId in this.registry)) {\n return Effect.fail(\n new PluginRuntimeError({\n pluginId: String(pluginId),\n operation: \"validate-plugin-id\",\n cause: new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),\n retryable: false,\n }),\n );\n }\n return Effect.succeed(String(pluginId));\n }\n\n private async runPromise<A, E>(effect: Effect.Effect<A, E, PluginService>): Promise<A> {\n const exit = await this.runtime.runPromiseExit(effect);\n\n if (Exit.isFailure(exit)) {\n const error = Cause.failureOption(exit.cause);\n if (Option.isSome(error)) {\n throw error.value;\n }\n throw Cause.squash(exit.cause);\n }\n\n return exit.value;\n }\n\n async usePlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n plugins?: Record<string, unknown>,\n ): Promise<UsePluginResult<K, R>> {\n const cacheKey = this.generateCacheKey(pluginId, { ...config, __plugins: plugins ?? {} });\n\n let cachedPlugin = this.pluginCache.get(cacheKey);\n if (!cachedPlugin) {\n const operation = Effect.gen(this, function* () {\n const pluginService = yield* PluginService;\n const validatedId = yield* this.validatePluginId(pluginId);\n\n // Load → Instantiate → Initialize\n const ctor = yield* pluginService.loadPlugin(validatedId);\n const instance = yield* pluginService.instantiatePlugin(pluginId, ctor);\n const initialized = yield* pluginService.initializePlugin(instance, config, plugins);\n\n return initialized;\n }).pipe(Effect.provide(this.runtime));\n\n cachedPlugin = Effect.cached(operation).pipe(Effect.flatten);\n this.pluginCache.set(cacheKey, cachedPlugin);\n }\n\n const initialized = await this.runPromise(cachedPlugin);\n\n // Create client factory that accepts request context\n const createClient = (context?: any) => {\n const router = initialized.plugin.createRouter(initialized.context);\n return createRouterClient(router, { context: context ?? {} });\n };\n\n return {\n createClient: createClient as any,\n router: initialized.plugin.createRouter(initialized.context) as PluginRouterType<R[K]>,\n metadata: initialized.metadata,\n initialized: initialized as InitializedPlugin<RegisteredPlugin<K, R>>,\n } as UsePluginResult<K, R>;\n }\n\n async loadPlugin<K extends keyof R & string>(\n pluginId: K,\n ): Promise<LoadedPlugin<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.loadPlugin(pluginId);\n });\n return this.runPromise(effect) as Promise<LoadedPlugin<RegisteredPlugin<K, R>>>;\n }\n\n async instantiatePlugin<K extends keyof R & string>(\n pluginId: K,\n loadedPlugin: LoadedPlugin<RegisteredPlugin<K, R>>,\n ): Promise<PluginInstance<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.instantiatePlugin(pluginId, loadedPlugin);\n });\n return this.runPromise(effect) as Promise<PluginInstance<RegisteredPlugin<K, R>>>;\n }\n\n async initializePlugin<T extends AnyPlugin>(\n instance: PluginInstance<T>,\n config: any,\n plugins?: Record<string, unknown>,\n ): Promise<InitializedPlugin<T>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.initializePlugin(instance, config, plugins);\n });\n return this.runPromise(effect);\n }\n\n async shutdown(): Promise<void> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n yield* pluginService.cleanup();\n });\n return this.runPromise(effect);\n }\n\n async evictPlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n ): Promise<void> {\n const cacheKey = this.generateCacheKey(pluginId, config);\n\n const effect = Effect.gen(this, function* () {\n const pluginService = yield* PluginService;\n const cachedPlugin = this.pluginCache.get(cacheKey);\n\n if (cachedPlugin) {\n this.pluginCache.delete(cacheKey);\n\n const pluginResult = yield* cachedPlugin.pipe(Effect.catchAll(() => Effect.succeed(null)));\n\n if (pluginResult) {\n yield* pluginService\n .shutdownPlugin(pluginResult)\n .pipe(Effect.catchAll(() => Effect.void));\n }\n }\n }).pipe(Effect.catchAll(() => Effect.void));\n\n return this.runPromise(effect);\n }\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 if (!url) return url;\n if (url.endsWith(\".js\") || url.endsWith(\".json\")) return url;\n return `${url.endsWith(\"/\") ? url.slice(0, -1) : url}/remoteEntry.js`;\n}\n\n/**\n * Extract plugin map (module constructors) from registry entries\n */\nfunction extractPluginMap(\n registry: Record<string, PluginRegistryEntry>,\n): Record<string, AnyPluginConstructor> {\n const pluginMap: Record<string, AnyPluginConstructor> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry && entry.module) {\n pluginMap[pluginId] = entry.module;\n }\n }\n\n return pluginMap;\n}\n\n/**\n * Normalize registry entries - ensure remote URLs are properly formatted\n */\nfunction normalizeRegistry(registry: Record<string, PluginRegistryEntry>): PluginRegistry {\n const normalized: Record<string, PluginRegistryEntry> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry) {\n normalized[pluginId] = {\n ...entry,\n remote: entry.remote ? normalizeRemoteUrl(entry.remote) : undefined,\n };\n } else {\n normalized[pluginId] = {\n ...entry,\n remote: normalizeRemoteUrl(entry.remote),\n };\n }\n }\n\n return 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 { router } = await runtime.usePlugin(\"telegram\", config);\n * ```\n */\nexport function createPluginRuntime<TRegistry extends Record<string, PluginRegistryEntry>>(\n config: PluginRuntimeConfig<TRegistry>,\n): PluginRuntime<InferRegistryFromEntries<TRegistry>> {\n const secrets = config.secrets || {};\n const normalizedRegistry = normalizeRegistry(config.registry);\n const pluginMap = extractPluginMap(config.registry);\n\n const layer = PluginService.Live(normalizedRegistry, secrets, pluginMap);\n const runtime = ManagedRuntime.make(layer);\n\n return new PluginRuntime(runtime, normalizedRegistry) as PluginRuntime<\n InferRegistryFromEntries<TRegistry>\n >;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/runtime/index.ts"],"sourcesContent":["import { createRouterClient } from \"@orpc/server\";\nimport { Cause, Effect, Exit, Hash, ManagedRuntime, Option } from \"effect\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InferRegistryFromEntries,\n InitializedPlugin,\n LoadedPlugin,\n PluginConfigInput,\n PluginInstance,\n PluginRegistry,\n PluginRegistryEntry,\n PluginRouterType,\n PluginRuntimeConfig,\n RegisteredPlugin,\n RegisteredPlugins,\n UsePluginResult,\n} from \"../types\";\nimport { PluginRuntimeError } from \"./errors\";\nimport { PluginService } from \"./services/plugin.service\";\n\nexport class PluginRuntime<R = RegisteredPlugins> {\n readonly __registryType?: R;\n\n private pluginCache = new Map<\n string,\n Effect.Effect<InitializedPlugin<AnyPlugin>, PluginRuntimeError>\n >();\n\n constructor(\n private runtime: ManagedRuntime.ManagedRuntime<PluginService, never>,\n private registry: PluginRegistry,\n ) {}\n\n private generateCacheKey(pluginId: string, config: unknown): string {\n const configHash = Hash.structure(config as object).toString();\n return `${pluginId}:${configHash}`;\n }\n\n private validatePluginId(pluginId: string): Effect.Effect<string, PluginRuntimeError> {\n if (!(pluginId in this.registry)) {\n return Effect.fail(\n new PluginRuntimeError({\n pluginId: String(pluginId),\n operation: \"validate-plugin-id\",\n cause: new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),\n retryable: false,\n }),\n );\n }\n return Effect.succeed(String(pluginId));\n }\n\n private async runPromise<A, E>(effect: Effect.Effect<A, E, PluginService>): Promise<A> {\n const exit = await this.runtime.runPromiseExit(effect);\n\n if (Exit.isFailure(exit)) {\n const error = Cause.failureOption(exit.cause);\n if (Option.isSome(error)) {\n throw error.value;\n }\n throw Cause.squash(exit.cause);\n }\n\n return exit.value;\n }\n\n async usePlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n plugins?: Record<string, unknown>,\n ): Promise<UsePluginResult<K, R>> {\n const cacheKey = this.generateCacheKey(pluginId, { ...config, __plugins: plugins ?? {} });\n\n let cachedPlugin = this.pluginCache.get(cacheKey);\n if (!cachedPlugin) {\n const operation = Effect.gen(this, function* () {\n const pluginService = yield* PluginService;\n const validatedId = yield* this.validatePluginId(pluginId);\n\n // Load → Instantiate → Initialize\n const ctor = yield* pluginService.loadPlugin(validatedId);\n const instance = yield* pluginService.instantiatePlugin(pluginId, ctor);\n const initialized = yield* pluginService.initializePlugin(instance, config, plugins);\n\n return initialized;\n }).pipe(Effect.provide(this.runtime));\n\n cachedPlugin = Effect.cached(operation).pipe(Effect.flatten);\n this.pluginCache.set(cacheKey, cachedPlugin);\n }\n\n const initialized = await this.runPromise(cachedPlugin);\n\n // Create client factory that accepts request context\n const createClient = (context?: any) => {\n const router = initialized.plugin.createRouter(initialized.context);\n return createRouterClient(router, { context: context ?? {} });\n };\n\n return {\n createClient: createClient as any,\n router: initialized.plugin.createRouter(initialized.context) as PluginRouterType<R[K]>,\n metadata: initialized.metadata,\n initialized: initialized as InitializedPlugin<RegisteredPlugin<K, R>>,\n } as UsePluginResult<K, R>;\n }\n\n async loadPlugin<K extends keyof R & string>(\n pluginId: K,\n ): Promise<LoadedPlugin<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.loadPlugin(pluginId);\n });\n return this.runPromise(effect) as Promise<LoadedPlugin<RegisteredPlugin<K, R>>>;\n }\n\n async instantiatePlugin<K extends keyof R & string>(\n pluginId: K,\n loadedPlugin: LoadedPlugin<RegisteredPlugin<K, R>>,\n ): Promise<PluginInstance<RegisteredPlugin<K, R>>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.instantiatePlugin(pluginId, loadedPlugin);\n });\n return this.runPromise(effect) as Promise<PluginInstance<RegisteredPlugin<K, R>>>;\n }\n\n async initializePlugin<T extends AnyPlugin>(\n instance: PluginInstance<T>,\n config: any,\n plugins?: Record<string, unknown>,\n ): Promise<InitializedPlugin<T>> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n return yield* pluginService.initializePlugin(instance, config, plugins);\n });\n return this.runPromise(effect);\n }\n\n async shutdown(): Promise<void> {\n const effect = Effect.gen(function* () {\n const pluginService = yield* PluginService;\n yield* pluginService.cleanup();\n });\n return this.runPromise(effect);\n }\n\n async evictPlugin<K extends keyof R & string>(\n pluginId: K,\n config: PluginConfigInput<R[K]>,\n ): Promise<void> {\n const cacheKey = this.generateCacheKey(pluginId, config);\n\n const effect = Effect.gen(this, function* () {\n const pluginService = yield* PluginService;\n const cachedPlugin = this.pluginCache.get(cacheKey);\n\n if (cachedPlugin) {\n this.pluginCache.delete(cacheKey);\n\n const pluginResult = yield* cachedPlugin.pipe(Effect.catchAll(() => Effect.succeed(null)));\n\n if (pluginResult) {\n yield* pluginService\n .shutdownPlugin(pluginResult)\n .pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(`Failed to shutdown evicted plugin ${pluginId}`, error),\n ),\n );\n }\n }\n }).pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(`Plugin eviction failed for ${pluginId}`, error),\n ),\n );\n\n return this.runPromise(effect);\n }\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 if (!url) return url;\n if (url.endsWith(\".js\") || url.endsWith(\".json\")) return url;\n return `${url.endsWith(\"/\") ? url.slice(0, -1) : url}/remoteEntry.js`;\n}\n\n/**\n * Extract plugin map (module constructors) from registry entries\n */\nfunction extractPluginMap(\n registry: Record<string, PluginRegistryEntry>,\n): Record<string, AnyPluginConstructor> {\n const pluginMap: Record<string, AnyPluginConstructor> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry && entry.module) {\n pluginMap[pluginId] = entry.module;\n }\n }\n\n return pluginMap;\n}\n\n/**\n * Normalize registry entries - ensure remote URLs are properly formatted\n */\nfunction normalizeRegistry(registry: Record<string, PluginRegistryEntry>): PluginRegistry {\n const normalized: Record<string, PluginRegistryEntry> = {};\n\n for (const [pluginId, entry] of Object.entries(registry)) {\n if (\"module\" in entry) {\n normalized[pluginId] = {\n ...entry,\n remote: entry.remote ? normalizeRemoteUrl(entry.remote) : undefined,\n };\n } else {\n normalized[pluginId] = {\n ...entry,\n remote: normalizeRemoteUrl(entry.remote),\n };\n }\n }\n\n return 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 { router } = await runtime.usePlugin(\"telegram\", config);\n * ```\n */\nexport function createPluginRuntime<TRegistry extends Record<string, PluginRegistryEntry>>(\n config: PluginRuntimeConfig<TRegistry>,\n): PluginRuntime<InferRegistryFromEntries<TRegistry>> {\n const secrets = config.secrets || {};\n const normalizedRegistry = normalizeRegistry(config.registry);\n const pluginMap = extractPluginMap(config.registry);\n\n const layer = PluginService.Live(normalizedRegistry, secrets, pluginMap);\n const runtime = ManagedRuntime.make(layer);\n\n return new PluginRuntime(runtime, normalizedRegistry) as PluginRuntime<\n InferRegistryFromEntries<TRegistry>\n >;\n}\n"],"mappings":"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"}
@@ -3,8 +3,16 @@ const require_runtime = require('../_virtual/_rolldown/runtime.cjs');
3
3
  let node_module = require("node:module");
4
4
 
5
5
  //#region src/runtime/mf-config.ts
6
- (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
7
- const PLUGIN_VERSION = "2.2.6";
6
+ const require$1 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
7
+ function getInstalledPackageVersion(packageName, fallbackRange) {
8
+ try {
9
+ return require$1(`${packageName}/package.json`).version;
10
+ } catch {
11
+ const match = fallbackRange.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
12
+ return match ? match[0] : fallbackRange.replace(/^[\^~>=<\s]+/, "");
13
+ }
14
+ }
15
+ const PLUGIN_VERSION = "2.4.0";
8
16
  const SHARE_CONFIG = {
9
17
  singleton: true,
10
18
  requiredVersion: false,
@@ -17,11 +25,11 @@ const MF_SHARED_DEPS = {
17
25
  shareConfig: SHARE_CONFIG
18
26
  },
19
27
  effect: {
20
- version: "^3.21.0",
28
+ version: getInstalledPackageVersion("effect", "^3.21.0"),
21
29
  shareConfig: SHARE_CONFIG
22
30
  },
23
31
  zod: {
24
- version: "^4.3.6",
32
+ version: getInstalledPackageVersion("zod", "^4.3.6"),
25
33
  shareConfig: SHARE_CONFIG
26
34
  }
27
35
  };
@@ -1 +1 @@
1
- {"version":3,"file":"mf-config.cjs","names":[],"sources":["../../src/runtime/mf-config.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\ndeclare const __EVERY_PLUGIN_VERSION__: string | undefined;\n\nfunction readPackageVersion(): string {\n try {\n return (require(\"../../package.json\") as { version: string }).version;\n } catch {\n return \"0.0.0\";\n }\n}\n\nexport const PLUGIN_VERSION =\n typeof __EVERY_PLUGIN_VERSION__ === \"string\" ? __EVERY_PLUGIN_VERSION__ : readPackageVersion();\n\nexport const SHARE_CONFIG = {\n singleton: true,\n requiredVersion: false,\n strictVersion: false,\n eager: false,\n} as const;\n\nexport const MF_SHARED_DEPS = {\n \"every-plugin\": {\n version: PLUGIN_VERSION,\n shareConfig: SHARE_CONFIG,\n },\n effect: {\n version: \"^3.21.0\",\n shareConfig: SHARE_CONFIG,\n },\n zod: {\n version: \"^4.3.6\",\n shareConfig: SHARE_CONFIG,\n },\n} as const;\n\nexport type SharedDepName = keyof typeof MF_SHARED_DEPS;\n"],"mappings":";;;;;6EAE8C;AAW9C,MAAa;AAGb,MAAa,eAAe;CAC1B,WAAW;CACX,iBAAiB;CACjB,eAAe;CACf,OAAO;CACR;AAED,MAAa,iBAAiB;CAC5B,gBAAgB;EACd,SAAS;EACT,aAAa;EACd;CACD,QAAQ;EACN,SAAS;EACT,aAAa;EACd;CACD,KAAK;EACH,SAAS;EACT,aAAa;EACd;CACF"}
1
+ {"version":3,"file":"mf-config.cjs","names":["require"],"sources":["../../src/runtime/mf-config.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\ndeclare const __EVERY_PLUGIN_VERSION__: string | undefined;\n\nfunction readPackageVersion(): string {\n try {\n return (require(\"../../package.json\") as { version: string }).version;\n } catch {\n return \"0.0.0\";\n }\n}\n\nfunction getInstalledPackageVersion(packageName: string, fallbackRange: string): string {\n try {\n return require(`${packageName}/package.json`).version as string;\n } catch {\n const match = fallbackRange.match(/\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?/);\n return match ? match[0] : fallbackRange.replace(/^[\\^~>=<\\s]+/, \"\");\n }\n}\n\nexport const PLUGIN_VERSION =\n typeof __EVERY_PLUGIN_VERSION__ === \"string\" ? __EVERY_PLUGIN_VERSION__ : readPackageVersion();\n\nexport const SHARE_CONFIG = {\n singleton: true,\n requiredVersion: false,\n strictVersion: false,\n eager: false,\n} as const;\n\nexport const MF_SHARED_DEPS = {\n \"every-plugin\": {\n version: PLUGIN_VERSION,\n shareConfig: SHARE_CONFIG,\n },\n effect: {\n version: getInstalledPackageVersion(\"effect\", \"^3.21.0\"),\n shareConfig: SHARE_CONFIG,\n },\n zod: {\n version: getInstalledPackageVersion(\"zod\", \"^4.3.6\"),\n shareConfig: SHARE_CONFIG,\n },\n} as const;\n\nexport type SharedDepName = keyof typeof MF_SHARED_DEPS;\n"],"mappings":";;;;;AAEA,MAAMA,yFAAwC;AAW9C,SAAS,2BAA2B,aAAqB,eAA+B;AACtF,KAAI;AACF,SAAOA,UAAQ,GAAG,YAAY,eAAe,CAAC;SACxC;EACN,MAAM,QAAQ,cAAc,MAAM,oCAAoC;AACtE,SAAO,QAAQ,MAAM,KAAK,cAAc,QAAQ,gBAAgB,GAAG;;;AAIvE,MAAa;AAGb,MAAa,eAAe;CAC1B,WAAW;CACX,iBAAiB;CACjB,eAAe;CACf,OAAO;CACR;AAED,MAAa,iBAAiB;CAC5B,gBAAgB;EACd,SAAS;EACT,aAAa;EACd;CACD,QAAQ;EACN,SAAS,2BAA2B,UAAU,UAAU;EACxD,aAAa;EACd;CACD,KAAK;EACH,SAAS,2BAA2B,OAAO,SAAS;EACpD,aAAa;EACd;CACF"}
@@ -17,7 +17,7 @@ declare const MF_SHARED_DEPS: {
17
17
  };
18
18
  };
19
19
  readonly effect: {
20
- readonly version: "^3.21.0";
20
+ readonly version: string;
21
21
  readonly shareConfig: {
22
22
  readonly singleton: true;
23
23
  readonly requiredVersion: false;
@@ -26,7 +26,7 @@ declare const MF_SHARED_DEPS: {
26
26
  };
27
27
  };
28
28
  readonly zod: {
29
- readonly version: "^4.3.6";
29
+ readonly version: string;
30
30
  readonly shareConfig: {
31
31
  readonly singleton: true;
32
32
  readonly requiredVersion: false;
@@ -1 +1 @@
1
- {"version":3,"file":"mf-config.d.cts","names":[],"sources":["../../src/runtime/mf-config.ts"],"mappings":";cAaa,cAAA;AAAA,cAGA,YAAA;EAAA;;;;;cAOA,cAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAeD,aAAA,gBAA6B,cAAA"}
1
+ {"version":3,"file":"mf-config.d.cts","names":[],"sources":["../../src/runtime/mf-config.ts"],"mappings":";cAsBa,cAAA;AAAA,cAGA,YAAA;EAAA;;;;;cAOA,cAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAeD,aAAA,gBAA6B,cAAA"}
@@ -17,7 +17,7 @@ declare const MF_SHARED_DEPS: {
17
17
  };
18
18
  };
19
19
  readonly effect: {
20
- readonly version: "^3.21.0";
20
+ readonly version: string;
21
21
  readonly shareConfig: {
22
22
  readonly singleton: true;
23
23
  readonly requiredVersion: false;
@@ -26,7 +26,7 @@ declare const MF_SHARED_DEPS: {
26
26
  };
27
27
  };
28
28
  readonly zod: {
29
- readonly version: "^4.3.6";
29
+ readonly version: string;
30
30
  readonly shareConfig: {
31
31
  readonly singleton: true;
32
32
  readonly requiredVersion: false;
@@ -1 +1 @@
1
- {"version":3,"file":"mf-config.d.mts","names":[],"sources":["../../src/runtime/mf-config.ts"],"mappings":";cAaa,cAAA;AAAA,cAGA,YAAA;EAAA;;;;;cAOA,cAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAeD,aAAA,gBAA6B,cAAA"}
1
+ {"version":3,"file":"mf-config.d.mts","names":[],"sources":["../../src/runtime/mf-config.ts"],"mappings":";cAsBa,cAAA;AAAA,cAGA,YAAA;EAAA;;;;;cAOA,cAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAeD,aAAA,gBAA6B,cAAA"}
@@ -1,8 +1,16 @@
1
1
  import { createRequire } from "node:module";
2
2
 
3
3
  //#region src/runtime/mf-config.ts
4
- createRequire(import.meta.url);
5
- const PLUGIN_VERSION = "2.2.6";
4
+ const require = createRequire(import.meta.url);
5
+ function getInstalledPackageVersion(packageName, fallbackRange) {
6
+ try {
7
+ return require(`${packageName}/package.json`).version;
8
+ } catch {
9
+ const match = fallbackRange.match(/\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?/);
10
+ return match ? match[0] : fallbackRange.replace(/^[\^~>=<\s]+/, "");
11
+ }
12
+ }
13
+ const PLUGIN_VERSION = "2.4.0";
6
14
  const SHARE_CONFIG = {
7
15
  singleton: true,
8
16
  requiredVersion: false,
@@ -15,11 +23,11 @@ const MF_SHARED_DEPS = {
15
23
  shareConfig: SHARE_CONFIG
16
24
  },
17
25
  effect: {
18
- version: "^3.21.0",
26
+ version: getInstalledPackageVersion("effect", "^3.21.0"),
19
27
  shareConfig: SHARE_CONFIG
20
28
  },
21
29
  zod: {
22
- version: "^4.3.6",
30
+ version: getInstalledPackageVersion("zod", "^4.3.6"),
23
31
  shareConfig: SHARE_CONFIG
24
32
  }
25
33
  };
@@ -1 +1 @@
1
- {"version":3,"file":"mf-config.mjs","names":[],"sources":["../../src/runtime/mf-config.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\ndeclare const __EVERY_PLUGIN_VERSION__: string | undefined;\n\nfunction readPackageVersion(): string {\n try {\n return (require(\"../../package.json\") as { version: string }).version;\n } catch {\n return \"0.0.0\";\n }\n}\n\nexport const PLUGIN_VERSION =\n typeof __EVERY_PLUGIN_VERSION__ === \"string\" ? __EVERY_PLUGIN_VERSION__ : readPackageVersion();\n\nexport const SHARE_CONFIG = {\n singleton: true,\n requiredVersion: false,\n strictVersion: false,\n eager: false,\n} as const;\n\nexport const MF_SHARED_DEPS = {\n \"every-plugin\": {\n version: PLUGIN_VERSION,\n shareConfig: SHARE_CONFIG,\n },\n effect: {\n version: \"^3.21.0\",\n shareConfig: SHARE_CONFIG,\n },\n zod: {\n version: \"^4.3.6\",\n shareConfig: SHARE_CONFIG,\n },\n} as const;\n\nexport type SharedDepName = keyof typeof MF_SHARED_DEPS;\n"],"mappings":";;;AAEgB,cAAc,OAAO,KAAK,IAAI;AAW9C,MAAa;AAGb,MAAa,eAAe;CAC1B,WAAW;CACX,iBAAiB;CACjB,eAAe;CACf,OAAO;CACR;AAED,MAAa,iBAAiB;CAC5B,gBAAgB;EACd,SAAS;EACT,aAAa;EACd;CACD,QAAQ;EACN,SAAS;EACT,aAAa;EACd;CACD,KAAK;EACH,SAAS;EACT,aAAa;EACd;CACF"}
1
+ {"version":3,"file":"mf-config.mjs","names":[],"sources":["../../src/runtime/mf-config.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\n\nconst require = createRequire(import.meta.url);\ndeclare const __EVERY_PLUGIN_VERSION__: string | undefined;\n\nfunction readPackageVersion(): string {\n try {\n return (require(\"../../package.json\") as { version: string }).version;\n } catch {\n return \"0.0.0\";\n }\n}\n\nfunction getInstalledPackageVersion(packageName: string, fallbackRange: string): string {\n try {\n return require(`${packageName}/package.json`).version as string;\n } catch {\n const match = fallbackRange.match(/\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?/);\n return match ? match[0] : fallbackRange.replace(/^[\\^~>=<\\s]+/, \"\");\n }\n}\n\nexport const PLUGIN_VERSION =\n typeof __EVERY_PLUGIN_VERSION__ === \"string\" ? __EVERY_PLUGIN_VERSION__ : readPackageVersion();\n\nexport const SHARE_CONFIG = {\n singleton: true,\n requiredVersion: false,\n strictVersion: false,\n eager: false,\n} as const;\n\nexport const MF_SHARED_DEPS = {\n \"every-plugin\": {\n version: PLUGIN_VERSION,\n shareConfig: SHARE_CONFIG,\n },\n effect: {\n version: getInstalledPackageVersion(\"effect\", \"^3.21.0\"),\n shareConfig: SHARE_CONFIG,\n },\n zod: {\n version: getInstalledPackageVersion(\"zod\", \"^4.3.6\"),\n shareConfig: SHARE_CONFIG,\n },\n} as const;\n\nexport type SharedDepName = keyof typeof MF_SHARED_DEPS;\n"],"mappings":";;;AAEA,MAAM,UAAU,cAAc,OAAO,KAAK,IAAI;AAW9C,SAAS,2BAA2B,aAAqB,eAA+B;AACtF,KAAI;AACF,SAAO,QAAQ,GAAG,YAAY,eAAe,CAAC;SACxC;EACN,MAAM,QAAQ,cAAc,MAAM,oCAAoC;AACtE,SAAO,QAAQ,MAAM,KAAK,cAAc,QAAQ,gBAAgB,GAAG;;;AAIvE,MAAa;AAGb,MAAa,eAAe;CAC1B,WAAW;CACX,iBAAiB;CACjB,eAAe;CACf,OAAO;CACR;AAED,MAAa,iBAAiB;CAC5B,gBAAgB;EACd,SAAS;EACT,aAAa;EACd;CACD,QAAQ;EACN,SAAS,2BAA2B,UAAU,UAAU;EACxD,aAAa;EACd;CACD,KAAK;EACH,SAAS,2BAA2B,OAAO,SAAS;EACpD,aAAa;EACd;CACF"}
@@ -22,9 +22,12 @@ var PluginLifecycleService = class extends effect.Effect.Service()("PluginLifecy
22
22
  }),
23
23
  cleanup: () => effect.Effect.gen(function* () {
24
24
  const plugins = yield* effect.Ref.get(activePlugins);
25
- yield* effect.Effect.forEach(plugins, (plugin) => plugin.plugin.shutdown().pipe(effect.Effect.mapError((error) => require_errors.toPluginRuntimeError(error, plugin.plugin.id, void 0, "cleanup-shutdown", false)), effect.Effect.catchAll((error) => effect.Effect.logError(`Failed to shutdown plugin ${plugin.plugin.id} during cleanup`, error, { pluginId: plugin.plugin.id }))), { concurrency: "unbounded" });
25
+ yield* effect.Effect.forEach(plugins, (plugin) => effect.Effect.gen(function* () {
26
+ yield* plugin.plugin.shutdown().pipe(effect.Effect.catchAll((error) => effect.Effect.logWarning(`Failed to shutdown plugin ${plugin.plugin.id}`, error)));
27
+ yield* effect.Scope.close(plugin.scope, effect.Exit.succeed(void 0)).pipe(effect.Effect.catchAll((error) => effect.Effect.logWarning(`Failed to close scope for plugin ${plugin.plugin.id}`, error)));
28
+ }), { concurrency: "unbounded" });
26
29
  yield* effect.Ref.set(activePlugins, /* @__PURE__ */ new Set());
27
- }).pipe(effect.Effect.catchAll(() => effect.Effect.void))
30
+ }).pipe(effect.Effect.catchAll((error) => effect.Effect.logWarning("Plugin cleanup failed", error)))
28
31
  };
29
32
  }) }) {};
30
33
 
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-lifecycle.service.cjs","names":["Effect","Ref","toPluginRuntimeError"],"sources":["../../../src/runtime/services/plugin-lifecycle.service.ts"],"sourcesContent":["import { Effect, Ref } from \"effect\";\nimport type { AnyPlugin, InitializedPlugin } from \"../../types\";\nimport { toPluginRuntimeError } from \"../errors\";\n\nexport class PluginLifecycleService extends Effect.Service<PluginLifecycleService>()(\n \"PluginLifecycleService\",\n {\n effect: Effect.gen(function* () {\n const activePlugins = yield* Ref.make(new Set<InitializedPlugin<AnyPlugin>>());\n\n return {\n register: <T extends AnyPlugin>(plugin: InitializedPlugin<T>) =>\n Ref.update(activePlugins, (plugins) =>\n new Set(plugins).add(plugin as InitializedPlugin<AnyPlugin>),\n ),\n\n unregister: (plugin: InitializedPlugin<AnyPlugin>) =>\n Ref.update(activePlugins, (plugins) => {\n const newSet = new Set(plugins);\n newSet.delete(plugin);\n return newSet;\n }),\n\n shutdown: (plugin: InitializedPlugin<AnyPlugin>) =>\n Effect.gen(function* () {\n // Remove from active plugins\n yield* Ref.update(activePlugins, (plugins) => {\n const newSet = new Set(plugins);\n newSet.delete(plugin);\n return newSet;\n });\n\n // Shutdown the plugin\n yield* plugin.plugin\n .shutdown()\n .pipe(\n Effect.mapError((error) =>\n toPluginRuntimeError(\n error,\n plugin.plugin.id,\n undefined,\n \"shutdown-plugin\",\n false,\n ),\n ),\n );\n }),\n\n cleanup: () =>\n Effect.gen(function* () {\n const plugins = yield* Ref.get(activePlugins);\n\n // Shutdown all active plugins concurrently\n yield* Effect.forEach(\n plugins,\n (plugin) =>\n plugin.plugin.shutdown().pipe(\n Effect.mapError((error) =>\n toPluginRuntimeError(\n error,\n plugin.plugin.id,\n undefined,\n \"cleanup-shutdown\",\n false,\n ),\n ),\n Effect.catchAll((error) =>\n Effect.logError(\n `Failed to shutdown plugin ${plugin.plugin.id} during cleanup`,\n error,\n { pluginId: plugin.plugin.id },\n ),\n ),\n ),\n { concurrency: \"unbounded\" },\n );\n\n // Clear the active plugins set\n yield* Ref.set(activePlugins, new Set());\n }).pipe(\n Effect.catchAll(() => Effect.void), // Convert errors to void for cleanup\n ),\n };\n }),\n },\n) {}\n"],"mappings":";;;;;AAIA,IAAa,yBAAb,cAA4CA,cAAO,SAAiC,CAClF,0BACA,EACE,QAAQA,cAAO,IAAI,aAAa;CAC9B,MAAM,gBAAgB,OAAOC,WAAI,qBAAK,IAAI,KAAmC,CAAC;AAE9E,QAAO;EACL,WAAgC,WAC9BA,WAAI,OAAO,gBAAgB,YACzB,IAAI,IAAI,QAAQ,CAAC,IAAI,OAAuC,CAC7D;EAEH,aAAa,WACXA,WAAI,OAAO,gBAAgB,YAAY;GACrC,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,UAAO,OAAO,OAAO;AACrB,UAAO;IACP;EAEJ,WAAW,WACTD,cAAO,IAAI,aAAa;AAEtB,UAAOC,WAAI,OAAO,gBAAgB,YAAY;IAC5C,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,WAAO,OAAO,OAAO;AACrB,WAAO;KACP;AAGF,UAAO,OAAO,OACX,UAAU,CACV,KACCD,cAAO,UAAU,UACfE,oCACE,OACA,OAAO,OAAO,IACd,QACA,mBACA,MACD,CACF,CACF;IACH;EAEJ,eACEF,cAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAOC,WAAI,IAAI,cAAc;AAG7C,UAAOD,cAAO,QACZ,UACC,WACC,OAAO,OAAO,UAAU,CAAC,KACvBA,cAAO,UAAU,UACfE,oCACE,OACA,OAAO,OAAO,IACd,QACA,oBACA,MACD,CACF,EACDF,cAAO,UAAU,UACfA,cAAO,SACL,6BAA6B,OAAO,OAAO,GAAG,kBAC9C,OACA,EAAE,UAAU,OAAO,OAAO,IAAI,CAC/B,CACF,CACF,EACH,EAAE,aAAa,aAAa,CAC7B;AAGD,UAAOC,WAAI,IAAI,+BAAe,IAAI,KAAK,CAAC;IACxC,CAAC,KACDD,cAAO,eAAeA,cAAO,KAAK,CACnC;EACJ;EACD,EACH,CACF,CAAC"}
1
+ {"version":3,"file":"plugin-lifecycle.service.cjs","names":["Effect","Ref","toPluginRuntimeError","Scope","Exit"],"sources":["../../../src/runtime/services/plugin-lifecycle.service.ts"],"sourcesContent":["import { Effect, Exit, Ref, Scope } from \"effect\";\nimport type { AnyPlugin, InitializedPlugin } from \"../../types\";\nimport { toPluginRuntimeError } from \"../errors\";\n\nexport class PluginLifecycleService extends Effect.Service<PluginLifecycleService>()(\n \"PluginLifecycleService\",\n {\n effect: Effect.gen(function* () {\n const activePlugins = yield* Ref.make(new Set<InitializedPlugin<AnyPlugin>>());\n\n return {\n register: <T extends AnyPlugin>(plugin: InitializedPlugin<T>) =>\n Ref.update(activePlugins, (plugins) =>\n new Set(plugins).add(plugin as InitializedPlugin<AnyPlugin>),\n ),\n\n unregister: (plugin: InitializedPlugin<AnyPlugin>) =>\n Ref.update(activePlugins, (plugins) => {\n const newSet = new Set(plugins);\n newSet.delete(plugin);\n return newSet;\n }),\n\n shutdown: (plugin: InitializedPlugin<AnyPlugin>) =>\n Effect.gen(function* () {\n // Remove from active plugins\n yield* Ref.update(activePlugins, (plugins) => {\n const newSet = new Set(plugins);\n newSet.delete(plugin);\n return newSet;\n });\n\n // Shutdown the plugin\n yield* plugin.plugin\n .shutdown()\n .pipe(\n Effect.mapError((error) =>\n toPluginRuntimeError(\n error,\n plugin.plugin.id,\n undefined,\n \"shutdown-plugin\",\n false,\n ),\n ),\n );\n }),\n\n cleanup: () =>\n Effect.gen(function* () {\n const plugins = yield* Ref.get(activePlugins);\n\n yield* Effect.forEach(\n plugins,\n (plugin) =>\n Effect.gen(function* () {\n yield* plugin.plugin\n .shutdown()\n .pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(`Failed to shutdown plugin ${plugin.plugin.id}`, error),\n ),\n );\n yield* Scope.close(plugin.scope, Exit.succeed(undefined)).pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(\n `Failed to close scope for plugin ${plugin.plugin.id}`,\n error,\n ),\n ),\n );\n }),\n { concurrency: \"unbounded\" },\n );\n\n yield* Ref.set(activePlugins, new Set());\n }).pipe(Effect.catchAll((error) => Effect.logWarning(\"Plugin cleanup failed\", error))),\n };\n }),\n },\n) {}\n"],"mappings":";;;;;AAIA,IAAa,yBAAb,cAA4CA,cAAO,SAAiC,CAClF,0BACA,EACE,QAAQA,cAAO,IAAI,aAAa;CAC9B,MAAM,gBAAgB,OAAOC,WAAI,qBAAK,IAAI,KAAmC,CAAC;AAE9E,QAAO;EACL,WAAgC,WAC9BA,WAAI,OAAO,gBAAgB,YACzB,IAAI,IAAI,QAAQ,CAAC,IAAI,OAAuC,CAC7D;EAEH,aAAa,WACXA,WAAI,OAAO,gBAAgB,YAAY;GACrC,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,UAAO,OAAO,OAAO;AACrB,UAAO;IACP;EAEJ,WAAW,WACTD,cAAO,IAAI,aAAa;AAEtB,UAAOC,WAAI,OAAO,gBAAgB,YAAY;IAC5C,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,WAAO,OAAO,OAAO;AACrB,WAAO;KACP;AAGF,UAAO,OAAO,OACX,UAAU,CACV,KACCD,cAAO,UAAU,UACfE,oCACE,OACA,OAAO,OAAO,IACd,QACA,mBACA,MACD,CACF,CACF;IACH;EAEJ,eACEF,cAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAOC,WAAI,IAAI,cAAc;AAE7C,UAAOD,cAAO,QACZ,UACC,WACCA,cAAO,IAAI,aAAa;AACtB,WAAO,OAAO,OACX,UAAU,CACV,KACCA,cAAO,UAAU,UACfA,cAAO,WAAW,6BAA6B,OAAO,OAAO,MAAM,MAAM,CAC1E,CACF;AACH,WAAOG,aAAM,MAAM,OAAO,OAAOC,YAAK,QAAQ,OAAU,CAAC,CAAC,KACxDJ,cAAO,UAAU,UACfA,cAAO,WACL,oCAAoC,OAAO,OAAO,MAClD,MACD,CACF,CACF;KACD,EACJ,EAAE,aAAa,aAAa,CAC7B;AAED,UAAOC,WAAI,IAAI,+BAAe,IAAI,KAAK,CAAC;IACxC,CAAC,KAAKD,cAAO,UAAU,UAAUA,cAAO,WAAW,yBAAyB,MAAM,CAAC,CAAC;EACzF;EACD,EACH,CACF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { toPluginRuntimeError } from "../errors.mjs";
2
- import { Effect, Ref } from "effect";
2
+ import { Effect, Exit, Ref, Scope } from "effect";
3
3
 
4
4
  //#region src/runtime/services/plugin-lifecycle.service.ts
5
5
  var PluginLifecycleService = class extends Effect.Service()("PluginLifecycleService", { effect: Effect.gen(function* () {
@@ -21,9 +21,12 @@ var PluginLifecycleService = class extends Effect.Service()("PluginLifecycleServ
21
21
  }),
22
22
  cleanup: () => Effect.gen(function* () {
23
23
  const plugins = yield* Ref.get(activePlugins);
24
- yield* Effect.forEach(plugins, (plugin) => plugin.plugin.shutdown().pipe(Effect.mapError((error) => toPluginRuntimeError(error, plugin.plugin.id, void 0, "cleanup-shutdown", false)), Effect.catchAll((error) => Effect.logError(`Failed to shutdown plugin ${plugin.plugin.id} during cleanup`, error, { pluginId: plugin.plugin.id }))), { concurrency: "unbounded" });
24
+ yield* Effect.forEach(plugins, (plugin) => Effect.gen(function* () {
25
+ yield* plugin.plugin.shutdown().pipe(Effect.catchAll((error) => Effect.logWarning(`Failed to shutdown plugin ${plugin.plugin.id}`, error)));
26
+ yield* Scope.close(plugin.scope, Exit.succeed(void 0)).pipe(Effect.catchAll((error) => Effect.logWarning(`Failed to close scope for plugin ${plugin.plugin.id}`, error)));
27
+ }), { concurrency: "unbounded" });
25
28
  yield* Ref.set(activePlugins, /* @__PURE__ */ new Set());
26
- }).pipe(Effect.catchAll(() => Effect.void))
29
+ }).pipe(Effect.catchAll((error) => Effect.logWarning("Plugin cleanup failed", error)))
27
30
  };
28
31
  }) }) {};
29
32
 
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-lifecycle.service.mjs","names":[],"sources":["../../../src/runtime/services/plugin-lifecycle.service.ts"],"sourcesContent":["import { Effect, Ref } from \"effect\";\nimport type { AnyPlugin, InitializedPlugin } from \"../../types\";\nimport { toPluginRuntimeError } from \"../errors\";\n\nexport class PluginLifecycleService extends Effect.Service<PluginLifecycleService>()(\n \"PluginLifecycleService\",\n {\n effect: Effect.gen(function* () {\n const activePlugins = yield* Ref.make(new Set<InitializedPlugin<AnyPlugin>>());\n\n return {\n register: <T extends AnyPlugin>(plugin: InitializedPlugin<T>) =>\n Ref.update(activePlugins, (plugins) =>\n new Set(plugins).add(plugin as InitializedPlugin<AnyPlugin>),\n ),\n\n unregister: (plugin: InitializedPlugin<AnyPlugin>) =>\n Ref.update(activePlugins, (plugins) => {\n const newSet = new Set(plugins);\n newSet.delete(plugin);\n return newSet;\n }),\n\n shutdown: (plugin: InitializedPlugin<AnyPlugin>) =>\n Effect.gen(function* () {\n // Remove from active plugins\n yield* Ref.update(activePlugins, (plugins) => {\n const newSet = new Set(plugins);\n newSet.delete(plugin);\n return newSet;\n });\n\n // Shutdown the plugin\n yield* plugin.plugin\n .shutdown()\n .pipe(\n Effect.mapError((error) =>\n toPluginRuntimeError(\n error,\n plugin.plugin.id,\n undefined,\n \"shutdown-plugin\",\n false,\n ),\n ),\n );\n }),\n\n cleanup: () =>\n Effect.gen(function* () {\n const plugins = yield* Ref.get(activePlugins);\n\n // Shutdown all active plugins concurrently\n yield* Effect.forEach(\n plugins,\n (plugin) =>\n plugin.plugin.shutdown().pipe(\n Effect.mapError((error) =>\n toPluginRuntimeError(\n error,\n plugin.plugin.id,\n undefined,\n \"cleanup-shutdown\",\n false,\n ),\n ),\n Effect.catchAll((error) =>\n Effect.logError(\n `Failed to shutdown plugin ${plugin.plugin.id} during cleanup`,\n error,\n { pluginId: plugin.plugin.id },\n ),\n ),\n ),\n { concurrency: \"unbounded\" },\n );\n\n // Clear the active plugins set\n yield* Ref.set(activePlugins, new Set());\n }).pipe(\n Effect.catchAll(() => Effect.void), // Convert errors to void for cleanup\n ),\n };\n }),\n },\n) {}\n"],"mappings":";;;;AAIA,IAAa,yBAAb,cAA4C,OAAO,SAAiC,CAClF,0BACA,EACE,QAAQ,OAAO,IAAI,aAAa;CAC9B,MAAM,gBAAgB,OAAO,IAAI,qBAAK,IAAI,KAAmC,CAAC;AAE9E,QAAO;EACL,WAAgC,WAC9B,IAAI,OAAO,gBAAgB,YACzB,IAAI,IAAI,QAAQ,CAAC,IAAI,OAAuC,CAC7D;EAEH,aAAa,WACX,IAAI,OAAO,gBAAgB,YAAY;GACrC,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,UAAO,OAAO,OAAO;AACrB,UAAO;IACP;EAEJ,WAAW,WACT,OAAO,IAAI,aAAa;AAEtB,UAAO,IAAI,OAAO,gBAAgB,YAAY;IAC5C,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,WAAO,OAAO,OAAO;AACrB,WAAO;KACP;AAGF,UAAO,OAAO,OACX,UAAU,CACV,KACC,OAAO,UAAU,UACf,qBACE,OACA,OAAO,OAAO,IACd,QACA,mBACA,MACD,CACF,CACF;IACH;EAEJ,eACE,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,IAAI,IAAI,cAAc;AAG7C,UAAO,OAAO,QACZ,UACC,WACC,OAAO,OAAO,UAAU,CAAC,KACvB,OAAO,UAAU,UACf,qBACE,OACA,OAAO,OAAO,IACd,QACA,oBACA,MACD,CACF,EACD,OAAO,UAAU,UACf,OAAO,SACL,6BAA6B,OAAO,OAAO,GAAG,kBAC9C,OACA,EAAE,UAAU,OAAO,OAAO,IAAI,CAC/B,CACF,CACF,EACH,EAAE,aAAa,aAAa,CAC7B;AAGD,UAAO,IAAI,IAAI,+BAAe,IAAI,KAAK,CAAC;IACxC,CAAC,KACD,OAAO,eAAe,OAAO,KAAK,CACnC;EACJ;EACD,EACH,CACF,CAAC"}
1
+ {"version":3,"file":"plugin-lifecycle.service.mjs","names":[],"sources":["../../../src/runtime/services/plugin-lifecycle.service.ts"],"sourcesContent":["import { Effect, Exit, Ref, Scope } from \"effect\";\nimport type { AnyPlugin, InitializedPlugin } from \"../../types\";\nimport { toPluginRuntimeError } from \"../errors\";\n\nexport class PluginLifecycleService extends Effect.Service<PluginLifecycleService>()(\n \"PluginLifecycleService\",\n {\n effect: Effect.gen(function* () {\n const activePlugins = yield* Ref.make(new Set<InitializedPlugin<AnyPlugin>>());\n\n return {\n register: <T extends AnyPlugin>(plugin: InitializedPlugin<T>) =>\n Ref.update(activePlugins, (plugins) =>\n new Set(plugins).add(plugin as InitializedPlugin<AnyPlugin>),\n ),\n\n unregister: (plugin: InitializedPlugin<AnyPlugin>) =>\n Ref.update(activePlugins, (plugins) => {\n const newSet = new Set(plugins);\n newSet.delete(plugin);\n return newSet;\n }),\n\n shutdown: (plugin: InitializedPlugin<AnyPlugin>) =>\n Effect.gen(function* () {\n // Remove from active plugins\n yield* Ref.update(activePlugins, (plugins) => {\n const newSet = new Set(plugins);\n newSet.delete(plugin);\n return newSet;\n });\n\n // Shutdown the plugin\n yield* plugin.plugin\n .shutdown()\n .pipe(\n Effect.mapError((error) =>\n toPluginRuntimeError(\n error,\n plugin.plugin.id,\n undefined,\n \"shutdown-plugin\",\n false,\n ),\n ),\n );\n }),\n\n cleanup: () =>\n Effect.gen(function* () {\n const plugins = yield* Ref.get(activePlugins);\n\n yield* Effect.forEach(\n plugins,\n (plugin) =>\n Effect.gen(function* () {\n yield* plugin.plugin\n .shutdown()\n .pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(`Failed to shutdown plugin ${plugin.plugin.id}`, error),\n ),\n );\n yield* Scope.close(plugin.scope, Exit.succeed(undefined)).pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(\n `Failed to close scope for plugin ${plugin.plugin.id}`,\n error,\n ),\n ),\n );\n }),\n { concurrency: \"unbounded\" },\n );\n\n yield* Ref.set(activePlugins, new Set());\n }).pipe(Effect.catchAll((error) => Effect.logWarning(\"Plugin cleanup failed\", error))),\n };\n }),\n },\n) {}\n"],"mappings":";;;;AAIA,IAAa,yBAAb,cAA4C,OAAO,SAAiC,CAClF,0BACA,EACE,QAAQ,OAAO,IAAI,aAAa;CAC9B,MAAM,gBAAgB,OAAO,IAAI,qBAAK,IAAI,KAAmC,CAAC;AAE9E,QAAO;EACL,WAAgC,WAC9B,IAAI,OAAO,gBAAgB,YACzB,IAAI,IAAI,QAAQ,CAAC,IAAI,OAAuC,CAC7D;EAEH,aAAa,WACX,IAAI,OAAO,gBAAgB,YAAY;GACrC,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,UAAO,OAAO,OAAO;AACrB,UAAO;IACP;EAEJ,WAAW,WACT,OAAO,IAAI,aAAa;AAEtB,UAAO,IAAI,OAAO,gBAAgB,YAAY;IAC5C,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,WAAO,OAAO,OAAO;AACrB,WAAO;KACP;AAGF,UAAO,OAAO,OACX,UAAU,CACV,KACC,OAAO,UAAU,UACf,qBACE,OACA,OAAO,OAAO,IACd,QACA,mBACA,MACD,CACF,CACF;IACH;EAEJ,eACE,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,IAAI,IAAI,cAAc;AAE7C,UAAO,OAAO,QACZ,UACC,WACC,OAAO,IAAI,aAAa;AACtB,WAAO,OAAO,OACX,UAAU,CACV,KACC,OAAO,UAAU,UACf,OAAO,WAAW,6BAA6B,OAAO,OAAO,MAAM,MAAM,CAC1E,CACF;AACH,WAAO,MAAM,MAAM,OAAO,OAAO,KAAK,QAAQ,OAAU,CAAC,CAAC,KACxD,OAAO,UAAU,UACf,OAAO,WACL,oCAAoC,OAAO,OAAO,MAClD,MACD,CACF,CACF;KACD,EACJ,EAAE,aAAa,aAAa,CAC7B;AAED,UAAO,IAAI,IAAI,+BAAe,IAAI,KAAK,CAAC;IACxC,CAAC,KAAK,OAAO,UAAU,UAAU,OAAO,WAAW,yBAAyB,MAAM,CAAC,CAAC;EACzF;EACD,EACH,CACF,CAAC"}
@@ -14,7 +14,7 @@ var PluginService = class PluginService extends effect.Effect.Service()("PluginS
14
14
  instantiatePlugin: loader.instantiatePlugin,
15
15
  initializePlugin: loader.initializePlugin,
16
16
  shutdownPlugin: (plugin) => effect.Effect.gen(function* () {
17
- yield* plugin.plugin.shutdown().pipe(effect.Effect.catchAll(() => effect.Effect.void));
17
+ yield* plugin.plugin.shutdown().pipe(effect.Effect.catchAll((error) => effect.Effect.logWarning(`Failed to shutdown plugin ${plugin.plugin.id}`, error)));
18
18
  yield* effect.Scope.close(plugin.scope, effect.Exit.succeed(void 0));
19
19
  yield* lifecycle.unregister(plugin);
20
20
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.service.cjs","names":["Effect","PluginLoaderService","PluginLifecycleService","Scope","Exit","Layer","PluginRegistryTag","SecretsConfigTag","PluginMapTag","ModuleFederationService","SecretsService","RegistryService"],"sources":["../../../src/runtime/services/plugin.service.ts"],"sourcesContent":["import { Effect, Exit, Layer, Scope } from \"effect\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InitializedPlugin,\n PluginRegistry,\n SecretsConfig,\n} from \"../../types\";\nimport { ModuleFederationService } from \"./module-federation.service\";\nimport { PluginLifecycleService } from \"./plugin-lifecycle.service\";\nimport {\n PluginLoaderService,\n PluginMapTag,\n PluginRegistryTag,\n RegistryService,\n} from \"./plugin-loader.service\";\nimport { SecretsConfigTag, SecretsService } from \"./secrets.service\";\n\nexport class PluginService extends Effect.Service<PluginService>()(\"PluginService\", {\n scoped: Effect.gen(function* () {\n const loader = yield* PluginLoaderService;\n const lifecycle = yield* PluginLifecycleService;\n\n return {\n loadPlugin: loader.loadPlugin,\n instantiatePlugin: loader.instantiatePlugin,\n initializePlugin: loader.initializePlugin,\n shutdownPlugin: (plugin: InitializedPlugin<AnyPlugin>) =>\n Effect.gen(function* () {\n // Shutdown the plugin first (graceful cleanup)\n yield* plugin.plugin.shutdown().pipe(Effect.catchAll(() => Effect.void));\n\n // Close the plugin scope to interrupt fibers and release resources\n yield* Scope.close(plugin.scope, Exit.succeed(undefined));\n\n // Unregister from lifecycle tracking\n yield* lifecycle.unregister(plugin);\n }),\n cleanup: lifecycle.cleanup,\n };\n }),\n}) {\n static Live = (\n registry: PluginRegistry,\n secrets: SecretsConfig,\n pluginMap: Record<string, AnyPluginConstructor> = {},\n ) => {\n const contextLayer = Layer.mergeAll(\n Layer.succeed(PluginRegistryTag, registry),\n Layer.succeed(SecretsConfigTag, secrets),\n Layer.succeed(PluginMapTag, pluginMap),\n );\n\n const servicesLayer = Layer.mergeAll(\n ModuleFederationService.Default,\n SecretsService.Default,\n RegistryService.Default,\n PluginLifecycleService.Default,\n ).pipe(Layer.provide(contextLayer));\n\n return PluginService.Default.pipe(\n Layer.provide(PluginLoaderService.Default),\n Layer.provide(servicesLayer),\n );\n };\n}\n"],"mappings":";;;;;;;;AAkBA,IAAa,gBAAb,MAAa,sBAAsBA,cAAO,SAAwB,CAAC,iBAAiB,EAClF,QAAQA,cAAO,IAAI,aAAa;CAC9B,MAAM,SAAS,OAAOC;CACtB,MAAM,YAAY,OAAOC;AAEzB,QAAO;EACL,YAAY,OAAO;EACnB,mBAAmB,OAAO;EAC1B,kBAAkB,OAAO;EACzB,iBAAiB,WACfF,cAAO,IAAI,aAAa;AAEtB,UAAO,OAAO,OAAO,UAAU,CAAC,KAAKA,cAAO,eAAeA,cAAO,KAAK,CAAC;AAGxE,UAAOG,aAAM,MAAM,OAAO,OAAOC,YAAK,QAAQ,OAAU,CAAC;AAGzD,UAAO,UAAU,WAAW,OAAO;IACnC;EACJ,SAAS,UAAU;EACpB;EACD,EACH,CAAC,CAAC;CACD,OAAO,QACL,UACA,SACA,YAAkD,EAAE,KACjD;EACH,MAAM,eAAeC,aAAM,SACzBA,aAAM,QAAQC,iDAAmB,SAAS,EAC1CD,aAAM,QAAQE,0CAAkB,QAAQ,EACxCF,aAAM,QAAQG,4CAAc,UAAU,CACvC;EAED,MAAM,gBAAgBH,aAAM,SAC1BI,0DAAwB,SACxBC,uCAAe,SACfC,8CAAgB,SAChBT,wDAAuB,QACxB,CAAC,KAAKG,aAAM,QAAQ,aAAa,CAAC;AAEnC,SAAO,cAAc,QAAQ,KAC3BA,aAAM,QAAQJ,kDAAoB,QAAQ,EAC1CI,aAAM,QAAQ,cAAc,CAC7B"}
1
+ {"version":3,"file":"plugin.service.cjs","names":["Effect","PluginLoaderService","PluginLifecycleService","Scope","Exit","Layer","PluginRegistryTag","SecretsConfigTag","PluginMapTag","ModuleFederationService","SecretsService","RegistryService"],"sources":["../../../src/runtime/services/plugin.service.ts"],"sourcesContent":["import { Effect, Exit, Layer, Scope } from \"effect\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InitializedPlugin,\n PluginRegistry,\n SecretsConfig,\n} from \"../../types\";\nimport { ModuleFederationService } from \"./module-federation.service\";\nimport { PluginLifecycleService } from \"./plugin-lifecycle.service\";\nimport {\n PluginLoaderService,\n PluginMapTag,\n PluginRegistryTag,\n RegistryService,\n} from \"./plugin-loader.service\";\nimport { SecretsConfigTag, SecretsService } from \"./secrets.service\";\n\nexport class PluginService extends Effect.Service<PluginService>()(\"PluginService\", {\n scoped: Effect.gen(function* () {\n const loader = yield* PluginLoaderService;\n const lifecycle = yield* PluginLifecycleService;\n\n return {\n loadPlugin: loader.loadPlugin,\n instantiatePlugin: loader.instantiatePlugin,\n initializePlugin: loader.initializePlugin,\n shutdownPlugin: (plugin: InitializedPlugin<AnyPlugin>) =>\n Effect.gen(function* () {\n yield* plugin.plugin\n .shutdown()\n .pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(`Failed to shutdown plugin ${plugin.plugin.id}`, error),\n ),\n );\n\n yield* Scope.close(plugin.scope, Exit.succeed(undefined));\n\n yield* lifecycle.unregister(plugin);\n }),\n cleanup: lifecycle.cleanup,\n };\n }),\n}) {\n static Live = (\n registry: PluginRegistry,\n secrets: SecretsConfig,\n pluginMap: Record<string, AnyPluginConstructor> = {},\n ) => {\n const contextLayer = Layer.mergeAll(\n Layer.succeed(PluginRegistryTag, registry),\n Layer.succeed(SecretsConfigTag, secrets),\n Layer.succeed(PluginMapTag, pluginMap),\n );\n\n const servicesLayer = Layer.mergeAll(\n ModuleFederationService.Default,\n SecretsService.Default,\n RegistryService.Default,\n PluginLifecycleService.Default,\n ).pipe(Layer.provide(contextLayer));\n\n return PluginService.Default.pipe(\n Layer.provide(PluginLoaderService.Default),\n Layer.provide(servicesLayer),\n );\n };\n}\n"],"mappings":";;;;;;;;AAkBA,IAAa,gBAAb,MAAa,sBAAsBA,cAAO,SAAwB,CAAC,iBAAiB,EAClF,QAAQA,cAAO,IAAI,aAAa;CAC9B,MAAM,SAAS,OAAOC;CACtB,MAAM,YAAY,OAAOC;AAEzB,QAAO;EACL,YAAY,OAAO;EACnB,mBAAmB,OAAO;EAC1B,kBAAkB,OAAO;EACzB,iBAAiB,WACfF,cAAO,IAAI,aAAa;AACtB,UAAO,OAAO,OACX,UAAU,CACV,KACCA,cAAO,UAAU,UACfA,cAAO,WAAW,6BAA6B,OAAO,OAAO,MAAM,MAAM,CAC1E,CACF;AAEH,UAAOG,aAAM,MAAM,OAAO,OAAOC,YAAK,QAAQ,OAAU,CAAC;AAEzD,UAAO,UAAU,WAAW,OAAO;IACnC;EACJ,SAAS,UAAU;EACpB;EACD,EACH,CAAC,CAAC;CACD,OAAO,QACL,UACA,SACA,YAAkD,EAAE,KACjD;EACH,MAAM,eAAeC,aAAM,SACzBA,aAAM,QAAQC,iDAAmB,SAAS,EAC1CD,aAAM,QAAQE,0CAAkB,QAAQ,EACxCF,aAAM,QAAQG,4CAAc,UAAU,CACvC;EAED,MAAM,gBAAgBH,aAAM,SAC1BI,0DAAwB,SACxBC,uCAAe,SACfC,8CAAgB,SAChBT,wDAAuB,QACxB,CAAC,KAAKG,aAAM,QAAQ,aAAa,CAAC;AAEnC,SAAO,cAAc,QAAQ,KAC3BA,aAAM,QAAQJ,kDAAoB,QAAQ,EAC1CI,aAAM,QAAQ,cAAc,CAC7B"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.service.d.cts","names":[],"sources":["../../../src/runtime/services/plugin.service.ts"],"mappings":";;;;;;;;cAeiC,kBAAA;;;;;;;;;;;;;;;;;;;;;;;6BAYF,iBAAA,CAAkB,SAAA,MAAU,MAAA,CAAA,MAAA;;;;cAT9C,aAAA,SAAsB,kBAAA;EAAA,OAwB1B,IAAA,GACL,QAAA,EAAU,cAAA,EACV,OAAA,EAAS,aAAA,EACT,SAAA,GAAW,MAAA,SAAe,oBAAA,MAA0B,KAAA,CAAA,KAAA,CAAA,aAAA;AAAA"}
1
+ {"version":3,"file":"plugin.service.d.cts","names":[],"sources":["../../../src/runtime/services/plugin.service.ts"],"mappings":";;;;;;;;cAeiC,kBAAA;;;;;;;;;;;;;;;;;;;;;;;6BAYF,iBAAA,CAAkB,SAAA,MAAU,MAAA,CAAA,MAAA;;;;cAT9C,aAAA,SAAsB,kBAAA;EAAA,OA2B1B,IAAA,GACL,QAAA,EAAU,cAAA,EACV,OAAA,EAAS,aAAA,EACT,SAAA,GAAW,MAAA,SAAe,oBAAA,MAA0B,KAAA,CAAA,KAAA,CAAA,aAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.service.d.mts","names":[],"sources":["../../../src/runtime/services/plugin.service.ts"],"mappings":";;;;;;;;cAeiC,kBAAA;;;;;;;;;;;;;;;;;;;;;;;6BAYF,iBAAA,CAAkB,SAAA,MAAU,MAAA,CAAA,MAAA;;;;cAT9C,aAAA,SAAsB,kBAAA;EAAA,OAwB1B,IAAA,GACL,QAAA,EAAU,cAAA,EACV,OAAA,EAAS,aAAA,EACT,SAAA,GAAW,MAAA,SAAe,oBAAA,MAA0B,KAAA,CAAA,KAAA,CAAA,aAAA;AAAA"}
1
+ {"version":3,"file":"plugin.service.d.mts","names":[],"sources":["../../../src/runtime/services/plugin.service.ts"],"mappings":";;;;;;;;cAeiC,kBAAA;;;;;;;;;;;;;;;;;;;;;;;6BAYF,iBAAA,CAAkB,SAAA,MAAU,MAAA,CAAA,MAAA;;;;cAT9C,aAAA,SAAsB,kBAAA;EAAA,OA2B1B,IAAA,GACL,QAAA,EAAU,cAAA,EACV,OAAA,EAAS,aAAA,EACT,SAAA,GAAW,MAAA,SAAe,oBAAA,MAA0B,KAAA,CAAA,KAAA,CAAA,aAAA;AAAA"}
@@ -13,7 +13,7 @@ var PluginService = class PluginService extends Effect.Service()("PluginService"
13
13
  instantiatePlugin: loader.instantiatePlugin,
14
14
  initializePlugin: loader.initializePlugin,
15
15
  shutdownPlugin: (plugin) => Effect.gen(function* () {
16
- yield* plugin.plugin.shutdown().pipe(Effect.catchAll(() => Effect.void));
16
+ yield* plugin.plugin.shutdown().pipe(Effect.catchAll((error) => Effect.logWarning(`Failed to shutdown plugin ${plugin.plugin.id}`, error)));
17
17
  yield* Scope.close(plugin.scope, Exit.succeed(void 0));
18
18
  yield* lifecycle.unregister(plugin);
19
19
  }),
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.service.mjs","names":[],"sources":["../../../src/runtime/services/plugin.service.ts"],"sourcesContent":["import { Effect, Exit, Layer, Scope } from \"effect\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InitializedPlugin,\n PluginRegistry,\n SecretsConfig,\n} from \"../../types\";\nimport { ModuleFederationService } from \"./module-federation.service\";\nimport { PluginLifecycleService } from \"./plugin-lifecycle.service\";\nimport {\n PluginLoaderService,\n PluginMapTag,\n PluginRegistryTag,\n RegistryService,\n} from \"./plugin-loader.service\";\nimport { SecretsConfigTag, SecretsService } from \"./secrets.service\";\n\nexport class PluginService extends Effect.Service<PluginService>()(\"PluginService\", {\n scoped: Effect.gen(function* () {\n const loader = yield* PluginLoaderService;\n const lifecycle = yield* PluginLifecycleService;\n\n return {\n loadPlugin: loader.loadPlugin,\n instantiatePlugin: loader.instantiatePlugin,\n initializePlugin: loader.initializePlugin,\n shutdownPlugin: (plugin: InitializedPlugin<AnyPlugin>) =>\n Effect.gen(function* () {\n // Shutdown the plugin first (graceful cleanup)\n yield* plugin.plugin.shutdown().pipe(Effect.catchAll(() => Effect.void));\n\n // Close the plugin scope to interrupt fibers and release resources\n yield* Scope.close(plugin.scope, Exit.succeed(undefined));\n\n // Unregister from lifecycle tracking\n yield* lifecycle.unregister(plugin);\n }),\n cleanup: lifecycle.cleanup,\n };\n }),\n}) {\n static Live = (\n registry: PluginRegistry,\n secrets: SecretsConfig,\n pluginMap: Record<string, AnyPluginConstructor> = {},\n ) => {\n const contextLayer = Layer.mergeAll(\n Layer.succeed(PluginRegistryTag, registry),\n Layer.succeed(SecretsConfigTag, secrets),\n Layer.succeed(PluginMapTag, pluginMap),\n );\n\n const servicesLayer = Layer.mergeAll(\n ModuleFederationService.Default,\n SecretsService.Default,\n RegistryService.Default,\n PluginLifecycleService.Default,\n ).pipe(Layer.provide(contextLayer));\n\n return PluginService.Default.pipe(\n Layer.provide(PluginLoaderService.Default),\n Layer.provide(servicesLayer),\n );\n };\n}\n"],"mappings":";;;;;;;AAkBA,IAAa,gBAAb,MAAa,sBAAsB,OAAO,SAAwB,CAAC,iBAAiB,EAClF,QAAQ,OAAO,IAAI,aAAa;CAC9B,MAAM,SAAS,OAAO;CACtB,MAAM,YAAY,OAAO;AAEzB,QAAO;EACL,YAAY,OAAO;EACnB,mBAAmB,OAAO;EAC1B,kBAAkB,OAAO;EACzB,iBAAiB,WACf,OAAO,IAAI,aAAa;AAEtB,UAAO,OAAO,OAAO,UAAU,CAAC,KAAK,OAAO,eAAe,OAAO,KAAK,CAAC;AAGxE,UAAO,MAAM,MAAM,OAAO,OAAO,KAAK,QAAQ,OAAU,CAAC;AAGzD,UAAO,UAAU,WAAW,OAAO;IACnC;EACJ,SAAS,UAAU;EACpB;EACD,EACH,CAAC,CAAC;CACD,OAAO,QACL,UACA,SACA,YAAkD,EAAE,KACjD;EACH,MAAM,eAAe,MAAM,SACzB,MAAM,QAAQ,mBAAmB,SAAS,EAC1C,MAAM,QAAQ,kBAAkB,QAAQ,EACxC,MAAM,QAAQ,cAAc,UAAU,CACvC;EAED,MAAM,gBAAgB,MAAM,SAC1B,wBAAwB,SACxB,eAAe,SACf,gBAAgB,SAChB,uBAAuB,QACxB,CAAC,KAAK,MAAM,QAAQ,aAAa,CAAC;AAEnC,SAAO,cAAc,QAAQ,KAC3B,MAAM,QAAQ,oBAAoB,QAAQ,EAC1C,MAAM,QAAQ,cAAc,CAC7B"}
1
+ {"version":3,"file":"plugin.service.mjs","names":[],"sources":["../../../src/runtime/services/plugin.service.ts"],"sourcesContent":["import { Effect, Exit, Layer, Scope } from \"effect\";\nimport type {\n AnyPlugin,\n AnyPluginConstructor,\n InitializedPlugin,\n PluginRegistry,\n SecretsConfig,\n} from \"../../types\";\nimport { ModuleFederationService } from \"./module-federation.service\";\nimport { PluginLifecycleService } from \"./plugin-lifecycle.service\";\nimport {\n PluginLoaderService,\n PluginMapTag,\n PluginRegistryTag,\n RegistryService,\n} from \"./plugin-loader.service\";\nimport { SecretsConfigTag, SecretsService } from \"./secrets.service\";\n\nexport class PluginService extends Effect.Service<PluginService>()(\"PluginService\", {\n scoped: Effect.gen(function* () {\n const loader = yield* PluginLoaderService;\n const lifecycle = yield* PluginLifecycleService;\n\n return {\n loadPlugin: loader.loadPlugin,\n instantiatePlugin: loader.instantiatePlugin,\n initializePlugin: loader.initializePlugin,\n shutdownPlugin: (plugin: InitializedPlugin<AnyPlugin>) =>\n Effect.gen(function* () {\n yield* plugin.plugin\n .shutdown()\n .pipe(\n Effect.catchAll((error) =>\n Effect.logWarning(`Failed to shutdown plugin ${plugin.plugin.id}`, error),\n ),\n );\n\n yield* Scope.close(plugin.scope, Exit.succeed(undefined));\n\n yield* lifecycle.unregister(plugin);\n }),\n cleanup: lifecycle.cleanup,\n };\n }),\n}) {\n static Live = (\n registry: PluginRegistry,\n secrets: SecretsConfig,\n pluginMap: Record<string, AnyPluginConstructor> = {},\n ) => {\n const contextLayer = Layer.mergeAll(\n Layer.succeed(PluginRegistryTag, registry),\n Layer.succeed(SecretsConfigTag, secrets),\n Layer.succeed(PluginMapTag, pluginMap),\n );\n\n const servicesLayer = Layer.mergeAll(\n ModuleFederationService.Default,\n SecretsService.Default,\n RegistryService.Default,\n PluginLifecycleService.Default,\n ).pipe(Layer.provide(contextLayer));\n\n return PluginService.Default.pipe(\n Layer.provide(PluginLoaderService.Default),\n Layer.provide(servicesLayer),\n );\n };\n}\n"],"mappings":";;;;;;;AAkBA,IAAa,gBAAb,MAAa,sBAAsB,OAAO,SAAwB,CAAC,iBAAiB,EAClF,QAAQ,OAAO,IAAI,aAAa;CAC9B,MAAM,SAAS,OAAO;CACtB,MAAM,YAAY,OAAO;AAEzB,QAAO;EACL,YAAY,OAAO;EACnB,mBAAmB,OAAO;EAC1B,kBAAkB,OAAO;EACzB,iBAAiB,WACf,OAAO,IAAI,aAAa;AACtB,UAAO,OAAO,OACX,UAAU,CACV,KACC,OAAO,UAAU,UACf,OAAO,WAAW,6BAA6B,OAAO,OAAO,MAAM,MAAM,CAC1E,CACF;AAEH,UAAO,MAAM,MAAM,OAAO,OAAO,KAAK,QAAQ,OAAU,CAAC;AAEzD,UAAO,UAAU,WAAW,OAAO;IACnC;EACJ,SAAS,UAAU;EACpB;EACD,EACH,CAAC,CAAC;CACD,OAAO,QACL,UACA,SACA,YAAkD,EAAE,KACjD;EACH,MAAM,eAAe,MAAM,SACzB,MAAM,QAAQ,mBAAmB,SAAS,EAC1C,MAAM,QAAQ,kBAAkB,QAAQ,EACxC,MAAM,QAAQ,cAAc,UAAU,CACvC;EAED,MAAM,gBAAgB,MAAM,SAC1B,wBAAwB,SACxB,eAAe,SACf,gBAAgB,SAChB,uBAAuB,QACxB,CAAC,KAAK,MAAM,QAAQ,aAAa,CAAC;AAEnC,SAAO,cAAc,QAAQ,KAC3B,MAAM,QAAQ,oBAAoB,QAAQ,EAC1C,MAAM,QAAQ,cAAc,CAC7B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "every-plugin",
3
- "version": "2.2.6",
3
+ "version": "2.4.0",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -63,12 +63,7 @@ export function setupPluginMiddleware(
63
63
  const loaded = await runtime.usePlugin(pluginId, (devConfig?.config ?? defaultConfig) as any);
64
64
 
65
65
  cleanup = async () => {
66
- if (loaded && typeof (loaded as any).dispose === "function") {
67
- await (loaded as any).dispose();
68
- }
69
- if (runtime && typeof (runtime as any).cleanup === "function") {
70
- await (runtime as any).cleanup();
71
- }
66
+ if (runtime) await runtime.shutdown();
72
67
  handlers.rpc = null;
73
68
  handlers.api = null;
74
69
  if (devServer.app.locals.handlers) {
@@ -14,9 +14,15 @@ export interface EveryPluginOptions {
14
14
  dts?: boolean;
15
15
  }
16
16
 
17
+ export interface AdditionalExport {
18
+ srcPath: string;
19
+ exportNames: string[];
20
+ }
21
+
17
22
  export interface PluginManifestEmitterOptions {
18
23
  manifestFileName?: string;
19
24
  contractFileName?: string;
25
+ additionalExports?: AdditionalExport[];
20
26
  }
21
27
 
22
28
  export class EmitPluginManifest implements RspackPluginInstance {
@@ -73,7 +79,7 @@ export class EmitPluginManifest implements RspackPluginInstance {
73
79
  }
74
80
 
75
81
  const contractSha256 = crypto.createHash("sha256").update(contractTypes).digest("hex");
76
- const manifest = {
82
+ const manifest: Record<string, unknown> = {
77
83
  schemaVersion: 1,
78
84
  kind: "every-plugin/manifest",
79
85
  plugin: {
@@ -94,6 +100,37 @@ export class EmitPluginManifest implements RspackPluginInstance {
94
100
  },
95
101
  };
96
102
 
103
+ const additionalExportsEntries: Array<{ path: string; exports: string[]; sha256: string }> =
104
+ [];
105
+
106
+ if (this.options.additionalExports?.length) {
107
+ for (const additional of this.options.additionalExports) {
108
+ const sourcePath = path.join(context, "types", additional.srcPath);
109
+ const content = await tryReadFile(sourcePath);
110
+ if (!content) {
111
+ console.warn(
112
+ `[EmitPluginManifest] Additional export file not found at ${sourcePath}. Skipping.`,
113
+ );
114
+ continue;
115
+ }
116
+ const sha256 = crypto.createHash("sha256").update(content).digest("hex");
117
+ const distPath = `./types/${additional.srcPath}`;
118
+ additionalExportsEntries.push({
119
+ path: distPath,
120
+ exports: additional.exportNames,
121
+ sha256,
122
+ });
123
+
124
+ if (rawSource) {
125
+ compilation.emitAsset(`types/${additional.srcPath}`, new rawSource(content));
126
+ }
127
+ }
128
+
129
+ if (additionalExportsEntries.length > 0) {
130
+ manifest.additionalExports = additionalExportsEntries;
131
+ }
132
+ }
133
+
97
134
  if (rawSource) {
98
135
  compilation.emitAsset(
99
136
  manifestFileName,
package/src/index.ts CHANGED
@@ -23,4 +23,5 @@ export type {
23
23
  PluginVariables,
24
24
  RegisteredPlugins,
25
25
  SecretsConfig,
26
+ UsePluginResult,
26
27
  } from "./types";
package/src/plugin.ts CHANGED
@@ -152,8 +152,15 @@ export const createPlugin: CreatePluginFn = function createPlugin<
152
152
  const self = this;
153
153
  return Effect.gen(function* () {
154
154
  if (config.shutdown && self._deps) {
155
- yield* config.shutdown(self._deps).pipe(Effect.catchAll(() => Effect.void));
155
+ yield* config
156
+ .shutdown(self._deps)
157
+ .pipe(
158
+ Effect.catchAll((error) =>
159
+ Effect.logWarning(`Plugin shutdown hook failed for ${self.id}`, error),
160
+ ),
161
+ );
156
162
  }
163
+ self._deps = null;
157
164
  });
158
165
  }
159
166
 
@@ -165,10 +165,18 @@ export class PluginRuntime<R = RegisteredPlugins> {
165
165
  if (pluginResult) {
166
166
  yield* pluginService
167
167
  .shutdownPlugin(pluginResult)
168
- .pipe(Effect.catchAll(() => Effect.void));
168
+ .pipe(
169
+ Effect.catchAll((error) =>
170
+ Effect.logWarning(`Failed to shutdown evicted plugin ${pluginId}`, error),
171
+ ),
172
+ );
169
173
  }
170
174
  }
171
- }).pipe(Effect.catchAll(() => Effect.void));
175
+ }).pipe(
176
+ Effect.catchAll((error) =>
177
+ Effect.logWarning(`Plugin eviction failed for ${pluginId}`, error),
178
+ ),
179
+ );
172
180
 
173
181
  return this.runPromise(effect);
174
182
  }