every-plugin 0.4.3 → 0.4.5

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 (123) hide show
  1. package/dist/build/rspack/index.cjs +267 -0
  2. package/dist/build/rspack/index.d.cts +20 -0
  3. package/dist/build/rspack/index.d.mts +20 -0
  4. package/dist/build/rspack/index.mjs +265 -0
  5. package/dist/chunk-QQAxy9l9.mjs +31 -0
  6. package/dist/chunk-zltIcp7o.cjs +46 -0
  7. package/dist/effect.cjs +9 -0
  8. package/dist/effect.d.cts +1 -0
  9. package/dist/effect.d.mts +1 -0
  10. package/dist/effect.mjs +3 -0
  11. package/dist/errors-CVnoPl9v.cjs +68 -0
  12. package/dist/errors-Car4tFVP.d.mts +75 -0
  13. package/dist/errors-D7keKf7a.mjs +63 -0
  14. package/dist/errors-DKPPPYYT.d.cts +75 -0
  15. package/dist/errors.cjs +4 -0
  16. package/dist/errors.d.cts +3 -0
  17. package/dist/errors.d.mts +3 -0
  18. package/dist/errors.mjs +4 -0
  19. package/dist/fetch-Cc95-7kM.cjs +336 -0
  20. package/dist/fetch-KLktuWuM.mjs +335 -0
  21. package/dist/index-bwAhA9ca.d.mts +383 -0
  22. package/dist/index-matrPV4m.d.cts +382 -0
  23. package/dist/index.cjs +57 -0
  24. package/dist/index.d.cts +5 -0
  25. package/dist/index.d.mts +5 -0
  26. package/dist/index.mjs +52 -0
  27. package/dist/{runtime/services/normalize.d.ts → normalize-BLTyqFww.d.mts} +5 -2
  28. package/dist/{runtime/services/normalize.js → normalize-BW7kk8Lk.d.cts} +5 -1
  29. package/dist/normalize-D4Qh0wVk.cjs +28 -0
  30. package/dist/normalize-D7nae0Hn.mjs +22 -0
  31. package/dist/openapi.DrTcell5-C6kyDyUK.mjs +669 -0
  32. package/dist/openapi.DrTcell5-DDf4D5V3.cjs +687 -0
  33. package/dist/orpc.cjs +46 -0
  34. package/dist/orpc.d.cts +7 -0
  35. package/dist/orpc.d.mts +7 -0
  36. package/dist/orpc.mjs +11 -0
  37. package/dist/package-Ba1JsQFb.mjs +149 -0
  38. package/dist/package-C09aaCqd.cjs +154 -0
  39. package/dist/plugins-C-7lh5gK.cjs +128 -0
  40. package/dist/plugins-Ps5Xxpk2.mjs +128 -0
  41. package/dist/runtime/index.cjs +6 -0
  42. package/dist/runtime/index.d.cts +5 -0
  43. package/dist/runtime/index.d.mts +5 -0
  44. package/dist/runtime/index.mjs +5 -0
  45. package/dist/runtime/services/normalize.cjs +3 -0
  46. package/dist/runtime/services/normalize.d.cts +2 -0
  47. package/dist/runtime/services/normalize.d.mts +2 -0
  48. package/dist/runtime/services/normalize.mjs +3 -0
  49. package/dist/runtime-CdAK1Q5M.cjs +523 -0
  50. package/dist/runtime-I62RA1Vo.mjs +458 -0
  51. package/dist/standard-DaxKTFui.mjs +595 -0
  52. package/dist/standard-eUgUkWaf.cjs +702 -0
  53. package/dist/testing/index.cjs +78 -0
  54. package/dist/testing/index.d.cts +60 -0
  55. package/dist/testing/index.d.mts +60 -0
  56. package/dist/testing/index.mjs +75 -0
  57. package/dist/zod-A7Pti5IV.d.cts +4 -0
  58. package/dist/zod-BVo51kgJ.mjs +10 -0
  59. package/dist/zod-D4CFw8d9.d.mts +4 -0
  60. package/dist/zod-DYghWCz1.cjs +14 -0
  61. package/dist/zod.cjs +10 -0
  62. package/dist/zod.d.cts +2 -0
  63. package/dist/zod.d.mts +2 -0
  64. package/dist/zod.mjs +5 -0
  65. package/dist/zod4-BXTBR1od.cjs +318 -0
  66. package/dist/zod4-VpXuwRO7.mjs +317 -0
  67. package/package.json +64 -27
  68. package/dist/effect.d.ts +0 -2
  69. package/dist/effect.d.ts.map +0 -1
  70. package/dist/effect.js +0 -1
  71. package/dist/errors.d.ts +0 -70
  72. package/dist/errors.d.ts.map +0 -1
  73. package/dist/errors.js +0 -61
  74. package/dist/index.d.ts +0 -6
  75. package/dist/index.d.ts.map +0 -1
  76. package/dist/index.js +0 -5
  77. package/dist/orpc.d.ts +0 -10
  78. package/dist/orpc.d.ts.map +0 -1
  79. package/dist/orpc.js +0 -6
  80. package/dist/plugin.d.ts +0 -57
  81. package/dist/plugin.d.ts.map +0 -1
  82. package/dist/plugin.js +0 -43
  83. package/dist/runtime/errors.d.ts +0 -36
  84. package/dist/runtime/errors.d.ts.map +0 -1
  85. package/dist/runtime/errors.js +0 -47
  86. package/dist/runtime/index.d.ts +0 -20
  87. package/dist/runtime/index.d.ts.map +0 -1
  88. package/dist/runtime/index.js +0 -131
  89. package/dist/runtime/services/module-federation.service.d.ts +0 -13
  90. package/dist/runtime/services/module-federation.service.d.ts.map +0 -1
  91. package/dist/runtime/services/module-federation.service.js +0 -155
  92. package/dist/runtime/services/normalize.d.ts.map +0 -1
  93. package/dist/runtime/services/plugin-lifecycle.service.d.ts +0 -14
  94. package/dist/runtime/services/plugin-lifecycle.service.d.ts.map +0 -1
  95. package/dist/runtime/services/plugin-lifecycle.service.js +0 -34
  96. package/dist/runtime/services/plugin-loader.service.d.ts +0 -45
  97. package/dist/runtime/services/plugin-loader.service.d.ts.map +0 -1
  98. package/dist/runtime/services/plugin-loader.service.js +0 -93
  99. package/dist/runtime/services/plugin.service.d.ts +0 -36
  100. package/dist/runtime/services/plugin.service.d.ts.map +0 -1
  101. package/dist/runtime/services/plugin.service.js +0 -31
  102. package/dist/runtime/services/secrets.service.d.ts +0 -15
  103. package/dist/runtime/services/secrets.service.d.ts.map +0 -1
  104. package/dist/runtime/services/secrets.service.js +0 -35
  105. package/dist/runtime/services.d.ts +0 -6
  106. package/dist/runtime/services.d.ts.map +0 -1
  107. package/dist/runtime/services.js +0 -5
  108. package/dist/runtime/validation.d.ts +0 -5
  109. package/dist/runtime/validation.d.ts.map +0 -1
  110. package/dist/runtime/validation.js +0 -13
  111. package/dist/testing/index.d.ts +0 -59
  112. package/dist/testing/index.d.ts.map +0 -1
  113. package/dist/testing/index.js +0 -45
  114. package/dist/testing/mocks/module-federation.service.d.ts +0 -6
  115. package/dist/testing/mocks/module-federation.service.d.ts.map +0 -1
  116. package/dist/testing/mocks/module-federation.service.js +0 -29
  117. package/dist/tsconfig.tsbuildinfo +0 -1
  118. package/dist/types.d.ts +0 -187
  119. package/dist/types.d.ts.map +0 -1
  120. package/dist/types.js +0 -1
  121. package/dist/zod.d.ts +0 -2
  122. package/dist/zod.d.ts.map +0 -1
  123. package/dist/zod.js +0 -1
@@ -1,155 +0,0 @@
1
- import { betterFetch } from "@better-fetch/fetch";
2
- import { createInstance, getInstance, } from "@module-federation/enhanced/runtime";
3
- import { setGlobalFederationInstance } from "@module-federation/runtime-core";
4
- import { Effect } from "effect";
5
- import { ModuleFederationError } from "../errors";
6
- import { getNormalizedRemoteName } from "./normalize";
7
- import pkg from "../../../package.json";
8
- const createModuleFederationInstance = Effect.cached(Effect.sync(() => {
9
- try {
10
- let instance = getInstance();
11
- if (!instance) {
12
- instance = createInstance({
13
- name: "host",
14
- remotes: [],
15
- shared: {
16
- "every-plugin": {
17
- version: pkg.version,
18
- shareConfig: {
19
- singleton: true,
20
- requiredVersion: `^${pkg.version}`,
21
- eager: true,
22
- strictVersion: true,
23
- },
24
- },
25
- effect: {
26
- version: pkg.dependencies.effect,
27
- shareConfig: {
28
- singleton: true,
29
- requiredVersion: "^3.18.0", // Allow any 3.18.x patch version
30
- eager: true,
31
- strictVersion: true, // Enforce major/minor compatibility
32
- },
33
- },
34
- zod: {
35
- version: pkg.dependencies.zod,
36
- shareConfig: {
37
- singleton: true,
38
- requiredVersion: "^4.1.0", // Allow any 4.1.x patch version
39
- eager: true,
40
- strictVersion: true,
41
- },
42
- },
43
- "@orpc/contract": {
44
- version: pkg.dependencies["@orpc/contract"],
45
- shareConfig: {
46
- singleton: true,
47
- requiredVersion: "^1.8.0", // Allow any 1.8.x patch version
48
- eager: true,
49
- strictVersion: true,
50
- },
51
- },
52
- "@orpc/server": {
53
- version: pkg.dependencies["@orpc/server"],
54
- shareConfig: {
55
- singleton: true,
56
- requiredVersion: "^1.8.0", // Allow any 1.8.x patch version
57
- eager: true,
58
- strictVersion: true,
59
- },
60
- }
61
- },
62
- });
63
- setGlobalFederationInstance(instance);
64
- }
65
- return instance;
66
- }
67
- catch (error) {
68
- throw new Error(`Failed to initialize Module Federation: ${error}`);
69
- }
70
- }));
71
- export class ModuleFederationService extends Effect.Service()("ModuleFederationService", {
72
- effect: Effect.gen(function* () {
73
- const mf = yield* Effect.flatten(createModuleFederationInstance);
74
- return {
75
- registerRemote: (pluginId, url) => Effect.gen(function* () {
76
- console.log(`[MF] Registering ${pluginId}`);
77
- // Check if remote is available
78
- const { error } = yield* Effect.tryPromise({
79
- try: () => betterFetch(url, { method: "HEAD" }),
80
- catch: (error) => new ModuleFederationError({
81
- pluginId,
82
- remoteUrl: url,
83
- cause: error instanceof Error ? error : new Error(String(error)),
84
- }),
85
- });
86
- if (error) {
87
- console.log(`[MF] ❌ Remote not available for ${pluginId}`);
88
- return yield* Effect.fail(new ModuleFederationError({
89
- pluginId,
90
- remoteUrl: url,
91
- cause: new Error(`Remote not available (${url}): ${JSON.stringify(error)}`),
92
- }));
93
- }
94
- const remoteName = getNormalizedRemoteName(pluginId);
95
- yield* Effect.try({
96
- try: () => mf.registerRemotes([{ name: remoteName, entry: url }]),
97
- catch: (error) => new ModuleFederationError({
98
- pluginId,
99
- remoteUrl: url,
100
- cause: error instanceof Error ? error : new Error(String(error)),
101
- }),
102
- });
103
- console.log(`[MF] ✅ Registered ${pluginId}`);
104
- }),
105
- loadRemoteConstructor: (pluginId, url) => Effect.gen(function* () {
106
- const remoteName = getNormalizedRemoteName(pluginId);
107
- console.log(`[MF] Loading remote ${remoteName}`);
108
- const modulePath = `${remoteName}/plugin`;
109
- return yield* Effect.tryPromise({
110
- try: async () => {
111
- const container = await mf.loadRemote(modulePath);
112
- if (!container) {
113
- throw new Error(`No container returned for ${modulePath}`);
114
- }
115
- // Support multiple export patterns: direct function, default export, named exports
116
- const Constructor = typeof container === "function"
117
- ? container // Direct function export
118
- : container.default
119
- ? container.default // Default export
120
- : Object.values(container).find(// Named export fallback
121
- (exp) => typeof exp === "function" && exp.prototype?.constructor === exp);
122
- if (!Constructor || typeof Constructor !== "function") {
123
- const containerInfo = typeof container === "object"
124
- ? `Available exports: ${Object.keys(container).join(', ')}`
125
- : `Container type: ${typeof container}`;
126
- throw new Error(`No valid plugin constructor found for '${pluginId}'.\n` +
127
- `Supported patterns:\n` +
128
- ` - export const YourPlugin = createPlugin({...})\n` +
129
- ` - export default createPlugin({...})\n` +
130
- `${containerInfo}`);
131
- }
132
- // Validate it looks like a plugin constructor (has binding property)
133
- if (!Constructor.binding) {
134
- const containerInfo = typeof container === "object"
135
- ? `Found exports: ${Object.keys(container).join(', ')}`
136
- : `Container type: ${typeof container}`;
137
- throw new Error(`Invalid plugin constructor for '${pluginId}'. ` +
138
- `The exported value must be created with createPlugin(). ` +
139
- `Found a function but it's missing the required 'binding' property.\n` +
140
- `${containerInfo}`);
141
- }
142
- console.log(`[MF] ✅ Loaded constructor for ${pluginId}`);
143
- return Constructor;
144
- },
145
- catch: (error) => new ModuleFederationError({
146
- pluginId,
147
- remoteUrl: url,
148
- cause: error instanceof Error ? error : new Error(String(error)),
149
- }),
150
- });
151
- }),
152
- };
153
- }),
154
- }) {
155
- }
@@ -1 +0,0 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../../src/runtime/services/normalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,KAAG,MACG,CAAC"}
@@ -1,14 +0,0 @@
1
- import { Effect } from "effect";
2
- import type { AnyPlugin, InitializedPlugin } from "../../types";
3
- declare const PluginLifecycleService_base: Effect.Service.Class<PluginLifecycleService, "PluginLifecycleService", {
4
- readonly effect: Effect.Effect<{
5
- register: <T extends AnyPlugin>(plugin: InitializedPlugin<T>) => Effect.Effect<void, never, never>;
6
- unregister: (plugin: InitializedPlugin<AnyPlugin>) => Effect.Effect<void, never, never>;
7
- shutdown: (plugin: InitializedPlugin<AnyPlugin>) => Effect.Effect<void, import("../errors").PluginRuntimeError, never>;
8
- cleanup: () => Effect.Effect<void, never, never>;
9
- }, never, never>;
10
- }>;
11
- export declare class PluginLifecycleService extends PluginLifecycleService_base {
12
- }
13
- export {};
14
- //# sourceMappingURL=plugin-lifecycle.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-lifecycle.service.d.ts","sourceRoot":"","sources":["../../../src/runtime/services/plugin-lifecycle.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAO,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;;;mBAQ/C,CAAC,SAAS,SAAS,UAAU,iBAAiB,CAAC,CAAC,CAAC;6BAKvC,iBAAiB,CAAC,SAAS,CAAC;2BAO9B,iBAAiB,CAAC,SAAS,CAAC;;;;AAjBrD,qBAAa,sBAAuB,SAAQ,2BAgE1C;CAAI"}
@@ -1,34 +0,0 @@
1
- import { Effect, Ref } from "effect";
2
- import { toPluginRuntimeError } from "../errors";
3
- export class PluginLifecycleService extends Effect.Service()("PluginLifecycleService", {
4
- effect: Effect.gen(function* () {
5
- const activePlugins = yield* Ref.make(new Set());
6
- return {
7
- register: (plugin) => Ref.update(activePlugins, plugins => new Set(plugins).add(plugin)),
8
- unregister: (plugin) => Ref.update(activePlugins, plugins => {
9
- const newSet = new Set(plugins);
10
- newSet.delete(plugin);
11
- return newSet;
12
- }),
13
- shutdown: (plugin) => Effect.gen(function* () {
14
- // Remove from active plugins
15
- yield* Ref.update(activePlugins, plugins => {
16
- const newSet = new Set(plugins);
17
- newSet.delete(plugin);
18
- return newSet;
19
- });
20
- // Shutdown the plugin
21
- yield* plugin.plugin.shutdown().pipe(Effect.mapError(error => toPluginRuntimeError(error, plugin.plugin.id, undefined, "shutdown-plugin", false)));
22
- }),
23
- cleanup: () => Effect.gen(function* () {
24
- const plugins = yield* Ref.get(activePlugins);
25
- // Shutdown all active plugins concurrently
26
- yield* Effect.forEach(plugins, plugin => plugin.plugin.shutdown().pipe(Effect.mapError(error => toPluginRuntimeError(error, plugin.plugin.id, undefined, "cleanup-shutdown", false)), Effect.catchAll(error => Effect.logError(`Failed to shutdown plugin ${plugin.plugin.id} during cleanup`, error, { pluginId: plugin.plugin.id }))), { concurrency: "unbounded" });
27
- // Clear the active plugins set
28
- yield* Ref.set(activePlugins, new Set());
29
- }).pipe(Effect.catchAll(() => Effect.void) // Convert errors to void for cleanup
30
- ),
31
- };
32
- }),
33
- }) {
34
- }
@@ -1,45 +0,0 @@
1
- import type { InferSchemaInput, InferSchemaOutput } from "@orpc/contract";
2
- import { Context, Effect, Scope } from "effect";
3
- import type { AnyPlugin, LoadedPlugin, PluginInstance, PluginRegistry } from "../../types";
4
- import { PluginRuntimeError } from "../errors";
5
- import { ModuleFederationService } from "./module-federation.service";
6
- import { SecretsService } from "./secrets.service";
7
- declare const PluginRegistryTag_base: Context.TagClass<PluginRegistryTag, "PluginRegistry", PluginRegistry>;
8
- export declare class PluginRegistryTag extends PluginRegistryTag_base {
9
- }
10
- declare const RegistryService_base: Effect.Service.Class<RegistryService, "RegistryService", {
11
- readonly effect: Effect.Effect<{
12
- get: (pluginId: string) => Effect.Effect<import("../..").PluginMetadata, PluginRuntimeError, never>;
13
- }, never, PluginRegistryTag>;
14
- }>;
15
- export declare class RegistryService extends RegistryService_base {
16
- }
17
- declare const PluginLoaderService_base: Effect.Service.Class<PluginLoaderService, "PluginLoaderService", {
18
- readonly effect: Effect.Effect<{
19
- loadPlugin: (pluginId: string) => Effect.Effect<{
20
- ctor: new () => AnyPlugin;
21
- metadata: import("../..").PluginMetadata;
22
- }, PluginRuntimeError, never>;
23
- instantiatePlugin: <T extends AnyPlugin>(pluginId: string, loadedPlugin: LoadedPlugin<T>) => Effect.Effect<{
24
- plugin: T;
25
- metadata: import("../..").PluginMetadata;
26
- }, PluginRuntimeError, never>;
27
- initializePlugin: <T extends AnyPlugin>(pluginInstance: PluginInstance<T>, config: {
28
- variables: InferSchemaInput<T["configSchema"]["variables"]>;
29
- secrets: InferSchemaInput<T["configSchema"]["secrets"]>;
30
- }) => Effect.Effect<{
31
- plugin: T;
32
- metadata: import("../..").PluginMetadata;
33
- config: {
34
- variables: InferSchemaOutput<T["configSchema"]["variables"]>;
35
- secrets: InferSchemaOutput<T["configSchema"]["secrets"]>;
36
- };
37
- context: any;
38
- scope: Scope.CloseableScope;
39
- }, PluginRuntimeError, never>;
40
- }, never, ModuleFederationService | SecretsService | RegistryService>;
41
- }>;
42
- export declare class PluginLoaderService extends PluginLoaderService_base {
43
- }
44
- export {};
45
- //# sourceMappingURL=plugin-loader.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin-loader.service.d.ts","sourceRoot":"","sources":["../../../src/runtime/services/plugin-loader.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEhD,OAAO,KAAK,EACX,SAAS,EAET,YAAY,EACZ,cAAc,EACd,cAAc,EACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAwB,MAAM,WAAW,CAAC;AAErE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;;AAEnD,qBAAa,iBAAkB,SAAQ,sBAGpC;CAAI;;;wBAOY,MAAM;;;AALzB,qBAAa,eAAgB,SAAQ,oBAkBnC;CAAI;;;+BAgBoB,MAAM;;;;4BAyBT,CAAC,SAAS,SAAS,YAC5B,MAAM,gBACF,YAAY,CAAC,CAAC,CAAC;;;;2BAuBX,CAAC,SAAS,SAAS,kBACrB,cAAc,CAAC,CAAC,CAAC,UACzB;YAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;YAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;SAAE;;;;;;;;;;;;AAlEpI,qBAAa,mBAAoB,SAAQ,wBAoJvC;CACD"}
@@ -1,93 +0,0 @@
1
- import { Context, Effect, Scope } from "effect";
2
- import { PluginRuntimeError, toPluginRuntimeError } from "../errors";
3
- import { validate } from "../validation";
4
- import { ModuleFederationService } from "./module-federation.service";
5
- import { SecretsService } from "./secrets.service";
6
- export class PluginRegistryTag extends Context.Tag("PluginRegistry")() {
7
- }
8
- export class RegistryService extends Effect.Service()("RegistryService", {
9
- effect: Effect.gen(function* () {
10
- const registry = yield* PluginRegistryTag;
11
- return {
12
- get: (pluginId) => Effect.fromNullable(registry[pluginId]).pipe(Effect.mapError(() => new PluginRuntimeError({
13
- pluginId,
14
- operation: "validate-plugin-id",
15
- cause: new Error(`Plugin ${pluginId} not found in registry`),
16
- retryable: false,
17
- }))),
18
- };
19
- }),
20
- }) {
21
- }
22
- export class PluginLoaderService extends Effect.Service()("PluginLoaderService", {
23
- effect: Effect.gen(function* () {
24
- const moduleFederationService = yield* ModuleFederationService;
25
- const secretsService = yield* SecretsService;
26
- const registryService = yield* RegistryService;
27
- const resolveUrl = (baseUrl, version) => version && version !== "latest"
28
- ? baseUrl.replace("@latest", `@${version}`)
29
- : baseUrl;
30
- const getMetadata = (pluginId) => registryService.get(pluginId);
31
- return {
32
- loadPlugin: (pluginId) => Effect.gen(function* () {
33
- const metadata = yield* getMetadata(pluginId);
34
- const url = resolveUrl(metadata.remoteUrl);
35
- yield* moduleFederationService.registerRemote(pluginId, url).pipe(Effect.mapError((error) => toPluginRuntimeError(error.cause, pluginId, undefined, "register-remote", true)));
36
- yield* Effect.logDebug("Loading plugin", { pluginId, url });
37
- const ctor = yield* moduleFederationService.loadRemoteConstructor(pluginId, url).pipe(Effect.mapError((error) => toPluginRuntimeError(error.cause, pluginId, undefined, "load-remote", false)));
38
- return {
39
- ctor,
40
- metadata: metadata,
41
- };
42
- }),
43
- instantiatePlugin: (pluginId, loadedPlugin) => Effect.gen(function* () {
44
- const instance = yield* Effect.try(() => new loadedPlugin.ctor()).pipe(Effect.mapError((error) => toPluginRuntimeError(error, pluginId, undefined, "instantiate-plugin", false)));
45
- instance.id = pluginId;
46
- return {
47
- plugin: instance,
48
- metadata: loadedPlugin.metadata,
49
- };
50
- }),
51
- initializePlugin: (pluginInstance, config) => Effect.gen(function* () {
52
- const { plugin } = pluginInstance;
53
- // Validate and hydrate config
54
- const validatedVariables = yield* validate(plugin.configSchema.variables, config.variables, plugin.id, "config").pipe(Effect.mapError((validationError) => new PluginRuntimeError({
55
- pluginId: plugin.id,
56
- operation: "validate-config",
57
- cause: validationError.zodError,
58
- retryable: false,
59
- })));
60
- // Validate secrets
61
- const validatedSecrets = yield* validate(plugin.configSchema.secrets, config.secrets, plugin.id, "config").pipe(Effect.mapError((validationError) => new PluginRuntimeError({
62
- pluginId: plugin.id,
63
- operation: "validate-secrets",
64
- cause: validationError.zodError,
65
- retryable: false,
66
- })));
67
- // Hydrate secrets in variables
68
- const hydratedConfig = yield* secretsService.hydrateSecrets({
69
- variables: validatedVariables,
70
- secrets: validatedSecrets,
71
- });
72
- const _variables = yield* validate(plugin.configSchema.variables, hydratedConfig.variables, plugin.id, "config").pipe(Effect.mapError((validationError) => new PluginRuntimeError({
73
- pluginId: plugin.id,
74
- operation: "validate-hydrated-config",
75
- cause: validationError.zodError,
76
- retryable: false,
77
- })));
78
- // Create a long-lived scope for this plugin instance
79
- const scope = yield* Scope.make();
80
- // Initialize plugin within the scope
81
- const context = yield* plugin.initialize({ variables: _variables, secrets: hydratedConfig.secrets }).pipe(Effect.provideService(Scope.Scope, scope), Effect.mapError((error) => toPluginRuntimeError(error, plugin.id, undefined, "initialize-plugin", false)));
82
- return {
83
- plugin,
84
- metadata: pluginInstance.metadata,
85
- config: { variables: _variables, secrets: hydratedConfig.secrets },
86
- context,
87
- scope,
88
- };
89
- }),
90
- };
91
- }),
92
- }) {
93
- }
@@ -1,36 +0,0 @@
1
- import { Effect, Layer, Scope } from "effect";
2
- import type { AnyPlugin, InitializedPlugin, PluginRegistry, SecretsConfig } from "../../types";
3
- import { PluginLifecycleService } from "./plugin-lifecycle.service";
4
- import { PluginLoaderService } from "./plugin-loader.service";
5
- declare const PluginService_base: Effect.Service.Class<PluginService, "PluginService", {
6
- readonly scoped: Effect.Effect<{
7
- loadPlugin: (pluginId: string) => Effect.Effect<{
8
- ctor: new () => AnyPlugin;
9
- metadata: import("../..").PluginMetadata;
10
- }, import("../errors").PluginRuntimeError, never>;
11
- instantiatePlugin: <T extends AnyPlugin>(pluginId: string, loadedPlugin: import("../..").LoadedPlugin<T>) => Effect.Effect<{
12
- plugin: T;
13
- metadata: import("../..").PluginMetadata;
14
- }, import("../errors").PluginRuntimeError, never>;
15
- initializePlugin: <T extends AnyPlugin>(pluginInstance: import("../..").PluginInstance<T>, config: {
16
- variables: import("@orpc/contract").InferSchemaInput<T["configSchema"]["variables"]>;
17
- secrets: import("@orpc/contract").InferSchemaInput<T["configSchema"]["secrets"]>;
18
- }) => Effect.Effect<{
19
- plugin: T;
20
- metadata: import("../..").PluginMetadata;
21
- config: {
22
- variables: import("@orpc/contract").InferSchemaOutput<T["configSchema"]["variables"]>;
23
- secrets: import("@orpc/contract").InferSchemaOutput<T["configSchema"]["secrets"]>;
24
- };
25
- context: any;
26
- scope: Scope.CloseableScope;
27
- }, import("../errors").PluginRuntimeError, never>;
28
- shutdownPlugin: (plugin: InitializedPlugin<AnyPlugin>) => Effect.Effect<void, never, never>;
29
- cleanup: () => Effect.Effect<void, never, never>;
30
- }, never, PluginLifecycleService | PluginLoaderService>;
31
- }>;
32
- export declare class PluginService extends PluginService_base {
33
- static Live: (registry: PluginRegistry, secrets: SecretsConfig) => Layer.Layer<PluginService, never, never>;
34
- }
35
- export {};
36
- //# sourceMappingURL=plugin.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"plugin.service.d.ts","sourceRoot":"","sources":["../../../src/runtime/services/plugin.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAQ,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACpD,OAAO,KAAK,EACX,SAAS,EACT,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAsC,MAAM,yBAAyB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;iCAYtE,iBAAiB,CAAC,SAAS,CAAC;;;;AATxD,qBAAa,aAAc,SAAQ,kBAyBjC;IACD,MAAM,CAAC,IAAI,GAAI,UAAU,cAAc,EAAE,SAAS,aAAa,8CAmB9D;CACD"}
@@ -1,31 +0,0 @@
1
- import { Effect, Exit, Layer, Scope } from "effect";
2
- import { ModuleFederationService } from "./module-federation.service";
3
- import { PluginLifecycleService } from "./plugin-lifecycle.service";
4
- import { PluginLoaderService, PluginRegistryTag, RegistryService } from "./plugin-loader.service";
5
- import { SecretsConfigTag, SecretsService } from "./secrets.service";
6
- export class PluginService extends Effect.Service()("PluginService", {
7
- scoped: Effect.gen(function* () {
8
- const loader = yield* PluginLoaderService;
9
- const lifecycle = yield* PluginLifecycleService;
10
- return {
11
- loadPlugin: loader.loadPlugin,
12
- instantiatePlugin: loader.instantiatePlugin,
13
- initializePlugin: loader.initializePlugin,
14
- shutdownPlugin: (plugin) => Effect.gen(function* () {
15
- // Shutdown the plugin first (graceful cleanup)
16
- yield* plugin.plugin.shutdown().pipe(Effect.catchAll(() => Effect.void));
17
- // Close the plugin scope to interrupt fibers and release resources
18
- yield* Scope.close(plugin.scope, Exit.succeed(undefined));
19
- // Unregister from lifecycle tracking
20
- yield* lifecycle.unregister(plugin);
21
- }),
22
- cleanup: lifecycle.cleanup,
23
- };
24
- }),
25
- }) {
26
- static Live = (registry, secrets) => {
27
- const contextLayer = Layer.mergeAll(Layer.succeed(PluginRegistryTag, registry), Layer.succeed(SecretsConfigTag, secrets));
28
- const servicesLayer = Layer.mergeAll(ModuleFederationService.Default, SecretsService.Default, RegistryService.Default, PluginLifecycleService.Default).pipe(Layer.provide(contextLayer));
29
- return PluginService.Default.pipe(Layer.provide(PluginLoaderService.Default), Layer.provide(servicesLayer));
30
- };
31
- }
@@ -1,15 +0,0 @@
1
- import { Context, Effect } from "effect";
2
- import type { SecretsConfig } from "../../types";
3
- import { PluginRuntimeError } from "../errors";
4
- declare const SecretsConfigTag_base: Context.TagClass<SecretsConfigTag, "SecretsConfig", SecretsConfig>;
5
- export declare class SecretsConfigTag extends SecretsConfigTag_base {
6
- }
7
- declare const SecretsService_base: Effect.Service.Class<SecretsService, "SecretsService", {
8
- readonly effect: Effect.Effect<{
9
- hydrateSecrets: <T>(config: T) => Effect.Effect<T, PluginRuntimeError, never>;
10
- }, never, SecretsConfigTag>;
11
- }>;
12
- export declare class SecretsService extends SecretsService_base {
13
- }
14
- export {};
15
- //# sourceMappingURL=secrets.service.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"secrets.service.d.ts","sourceRoot":"","sources":["../../../src/runtime/services/secrets.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;;AAM/C,qBAAa,gBAAiB,SAAQ,qBAGnC;CAAI;;;yBAOa,CAAC,UAAU,CAAC;;;AALhC,qBAAa,cAAe,SAAQ,mBA+BlC;CAAI"}
@@ -1,35 +0,0 @@
1
- import { Context, Effect } from "effect";
2
- import { z } from "zod";
3
- import { PluginRuntimeError } from "../errors";
4
- const configSchema = z.object({
5
- secrets: z.record(z.string(), z.unknown())
6
- }).loose();
7
- export class SecretsConfigTag extends Context.Tag("SecretsConfig")() {
8
- }
9
- export class SecretsService extends Effect.Service()("SecretsService", {
10
- effect: Effect.gen(function* () {
11
- const secrets = yield* SecretsConfigTag;
12
- return {
13
- hydrateSecrets: (config) => Effect.gen(function* () {
14
- const parseResult = configSchema.parse(config);
15
- try {
16
- const configString = JSON.stringify(parseResult);
17
- let hydratedString = configString;
18
- for (const [key, value] of Object.entries(secrets)) {
19
- const pattern = new RegExp(`{{${key}}}`, "g");
20
- hydratedString = hydratedString.replace(pattern, String(value));
21
- }
22
- return JSON.parse(hydratedString);
23
- }
24
- catch (error) {
25
- return yield* Effect.fail(new PluginRuntimeError({
26
- operation: "hydrate-secrets",
27
- cause: error instanceof Error ? error : new Error(String(error)),
28
- retryable: false,
29
- }));
30
- }
31
- }),
32
- };
33
- }),
34
- }) {
35
- }
@@ -1,6 +0,0 @@
1
- export * from "./services/module-federation.service";
2
- export * from "./services/plugin.service";
3
- export * from "./services/plugin-lifecycle.service";
4
- export * from "./services/plugin-loader.service";
5
- export * from "./services/secrets.service";
6
- //# sourceMappingURL=services.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../../src/runtime/services.ts"],"names":[],"mappings":"AAAA,cAAc,sCAAsC,CAAA;AACpD,cAAc,2BAA2B,CAAA;AACzC,cAAc,qCAAqC,CAAA;AACnD,cAAc,kCAAkC,CAAA;AAChD,cAAc,4BAA4B,CAAA"}
@@ -1,5 +0,0 @@
1
- export * from "./services/module-federation.service";
2
- export * from "./services/plugin.service";
3
- export * from "./services/plugin-lifecycle.service";
4
- export * from "./services/plugin-loader.service";
5
- export * from "./services/secrets.service";
@@ -1,5 +0,0 @@
1
- import { Effect } from "effect";
2
- import type { z } from "zod";
3
- import { ValidationError } from "./errors";
4
- export declare const validate: <T>(schema: z.ZodSchema<T>, data: unknown, pluginId: string, stage: "config" | "input" | "output" | "state") => Effect.Effect<T, ValidationError>;
5
- //# sourceMappingURL=validation.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/runtime/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,eAAO,MAAM,QAAQ,GAAI,CAAC,EACzB,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACtB,MAAM,OAAO,EACb,UAAU,MAAM,EAChB,OAAO,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,KAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,eAAe,CAahC,CAAC"}
@@ -1,13 +0,0 @@
1
- import { Effect } from "effect";
2
- import { ValidationError } from "./errors";
3
- export const validate = (schema, data, pluginId, stage) => Effect.gen(function* () {
4
- const result = schema.safeParse(data);
5
- if (result.success) {
6
- return result.data;
7
- }
8
- return yield* Effect.fail(new ValidationError({
9
- pluginId,
10
- stage,
11
- zodError: result.error,
12
- }));
13
- });
@@ -1,59 +0,0 @@
1
- import { Layer } from "effect";
2
- import { PluginRuntime } from "../runtime";
3
- import { PluginService } from "../runtime/services";
4
- import type { PluginRuntimeConfig, RegisteredPlugins } from "../types";
5
- import { type PluginMap } from "./mocks/module-federation.service";
6
- /**
7
- * Validates that all plugin map keys exist in RegisteredPlugins.
8
- * This ensures proper type inference for client methods.
9
- */
10
- type ValidatePluginMap<T extends PluginMap> = {
11
- [K in keyof T]: K extends keyof RegisteredPlugins ? T[K] : `❌ Plugin key "${K & string}" not registered in RegisteredPlugins. Add it to your types.d.ts file.`;
12
- };
13
- /**
14
- * Simplified type inference for local plugin maps.
15
- * Just use the constructor types directly.
16
- *
17
- * @example
18
- * ```ts
19
- * const pluginMap = { "my-plugin": MyPlugin } as const;
20
- * type MyBindings = InferBindingsFromMap<typeof pluginMap>;
21
- * ```
22
- */
23
- export type InferBindingsFromMap<T extends PluginMap> = {
24
- [K in keyof T]: T[K];
25
- } & RegisteredPlugins;
26
- /**
27
- * Creates a test layer with mock ModuleFederationService for unit testing.
28
- * This mirrors PluginService.Live() but uses mock ModuleFederationService.
29
- */
30
- export declare const createTestLayer: <R extends RegisteredPlugins = RegisteredPlugins>(config: PluginRuntimeConfig<R>, pluginMap: PluginMap) => Layer.Layer<PluginService, never, never>;
31
- /**
32
- * Creates a plugin runtime for locally available plugins (non-remote).
33
- * Automatically infers type bindings from the plugin map, eliminating
34
- * the need for manual RegistryBindings definitions.
35
- *
36
- * Ideal for:
37
- * - Unit and integration tests
38
- * - Local development and debugging
39
- * - Monorepo setups where all plugins are in the same workspace
40
- *
41
- * For production with remote Module Federation plugins, use createPluginRuntime().
42
- *
43
- * @example
44
- * ```ts
45
- * const pluginMap = { "my-plugin": MyPlugin } as const;
46
- * const runtime = createLocalPluginRuntime({ registry, secrets }, pluginMap);
47
- *
48
- * // Types are automatically inferred - no manual bindings needed!
49
- * const plugin = await runtime.usePlugin("my-plugin", config);
50
- * ```
51
- */
52
- export declare function createLocalPluginRuntime<TMap extends PluginMap & ValidatePluginMap<TMap>>(config: PluginRuntimeConfig, pluginMap: TMap): PluginRuntime<InferBindingsFromMap<TMap>>;
53
- /**
54
- * @deprecated Use `createLocalPluginRuntime` instead. This alias is kept for backward compatibility.
55
- */
56
- export declare const createTestPluginRuntime: typeof createLocalPluginRuntime;
57
- export type { EveryPlugin, PluginRegistry, RegisteredPlugins } from "../types";
58
- export type { PluginMap, PluginRuntimeConfig };
59
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAkB,MAAM,QAAQ,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAIN,aAAa,EAIb,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACvE,OAAO,EAA0C,KAAK,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAE3G;;;GAGG;AACH,KAAK,iBAAiB,CAAC,CAAC,SAAS,SAAS,IAAI;KAC5C,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,SAAS,MAAM,iBAAiB,GAC9C,CAAC,CAAC,CAAC,CAAC,GACJ,iBAAiB,CAAC,GAAG,MAAM,wEAAwE;CACtG,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,SAAS,IAAI;KACtD,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CACpB,GAAG,iBAAiB,CAAC;AAEtB;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAI,CAAC,SAAS,iBAAiB,GAAG,iBAAiB,EAC9E,QAAQ,mBAAmB,CAAC,CAAC,CAAC,EAC9B,WAAW,SAAS,6CAwBpB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,SAAS,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,EACxF,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,IAAI,GACb,aAAa,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAK3C;AAED;;GAEG;AACH,eAAO,MAAM,uBAAuB,iCAA2B,CAAC;AAGhE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC/E,YAAY,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC"}
@@ -1,45 +0,0 @@
1
- import { Layer, ManagedRuntime } from "effect";
2
- import { PluginRuntime } from "../runtime";
3
- import { PluginLifecycleService, PluginLoaderService, PluginRegistryTag, PluginService, RegistryService, SecretsConfigTag, SecretsService } from "../runtime/services";
4
- import { createMockModuleFederationServiceLayer } from "./mocks/module-federation.service";
5
- /**
6
- * Creates a test layer with mock ModuleFederationService for unit testing.
7
- * This mirrors PluginService.Live() but uses mock ModuleFederationService.
8
- */
9
- export const createTestLayer = (config, pluginMap) => {
10
- const secrets = config.secrets || {};
11
- const contextLayer = Layer.mergeAll(Layer.succeed(PluginRegistryTag, config.registry), Layer.succeed(SecretsConfigTag, secrets));
12
- const mockModuleFederationLayer = createMockModuleFederationServiceLayer(pluginMap);
13
- const servicesLayer = Layer.mergeAll(mockModuleFederationLayer, SecretsService.Default, RegistryService.Default, PluginLifecycleService.Default).pipe(Layer.provide(contextLayer));
14
- return PluginService.Default.pipe(Layer.provide(PluginLoaderService.Default), Layer.provide(servicesLayer));
15
- };
16
- /**
17
- * Creates a plugin runtime for locally available plugins (non-remote).
18
- * Automatically infers type bindings from the plugin map, eliminating
19
- * the need for manual RegistryBindings definitions.
20
- *
21
- * Ideal for:
22
- * - Unit and integration tests
23
- * - Local development and debugging
24
- * - Monorepo setups where all plugins are in the same workspace
25
- *
26
- * For production with remote Module Federation plugins, use createPluginRuntime().
27
- *
28
- * @example
29
- * ```ts
30
- * const pluginMap = { "my-plugin": MyPlugin } as const;
31
- * const runtime = createLocalPluginRuntime({ registry, secrets }, pluginMap);
32
- *
33
- * // Types are automatically inferred - no manual bindings needed!
34
- * const plugin = await runtime.usePlugin("my-plugin", config);
35
- * ```
36
- */
37
- export function createLocalPluginRuntime(config, pluginMap) {
38
- const layer = createTestLayer(config, pluginMap);
39
- const runtime = ManagedRuntime.make(layer);
40
- return new PluginRuntime(runtime, config.registry);
41
- }
42
- /**
43
- * @deprecated Use `createLocalPluginRuntime` instead. This alias is kept for backward compatibility.
44
- */
45
- export const createTestPluginRuntime = createLocalPluginRuntime;