every-plugin 0.4.17 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-zltIcp7o.cjs → _virtual/rolldown_runtime.cjs} +3 -18
- package/dist/{chunk-QQAxy9l9.mjs → _virtual/rolldown_runtime.mjs} +1 -1
- package/dist/build/rspack/dev-server-middleware.cjs +201 -0
- package/dist/build/rspack/dev-server-middleware.cjs.map +1 -0
- package/dist/build/rspack/dev-server-middleware.mjs +200 -0
- package/dist/build/rspack/dev-server-middleware.mjs.map +1 -0
- package/dist/build/rspack/index.cjs +2 -362
- package/dist/build/rspack/index.d.cts +2 -20
- package/dist/build/rspack/index.d.mts +2 -20
- package/dist/build/rspack/index.mjs +2 -360
- package/dist/build/rspack/module-federation.cjs +47 -0
- package/dist/build/rspack/module-federation.cjs.map +1 -0
- package/dist/build/rspack/module-federation.mjs +47 -0
- package/dist/build/rspack/module-federation.mjs.map +1 -0
- package/dist/build/rspack/plugin.cjs +90 -0
- package/dist/build/rspack/plugin.cjs.map +1 -0
- package/dist/build/rspack/plugin.d.cts +20 -0
- package/dist/build/rspack/plugin.d.cts.map +1 -0
- package/dist/build/rspack/plugin.d.mts +20 -0
- package/dist/build/rspack/plugin.d.mts.map +1 -0
- package/dist/build/rspack/plugin.mjs +89 -0
- package/dist/build/rspack/plugin.mjs.map +1 -0
- package/dist/build/rspack/utils.cjs +41 -0
- package/dist/build/rspack/utils.cjs.map +1 -0
- package/dist/build/rspack/utils.mjs +38 -0
- package/dist/build/rspack/utils.mjs.map +1 -0
- package/dist/errors.cjs +62 -3
- package/dist/errors.cjs.map +1 -0
- package/dist/errors.d.cts +75 -3
- package/dist/errors.d.cts.map +1 -0
- package/dist/errors.d.mts +75 -3
- package/dist/errors.d.mts.map +1 -0
- package/dist/errors.mjs +62 -3
- package/dist/errors.mjs.map +1 -0
- package/dist/index.cjs +8 -55
- package/dist/index.d.cts +6 -5
- package/dist/index.d.mts +6 -5
- package/dist/index.mjs +5 -51
- package/dist/orpc.cjs +1 -1
- package/dist/{package-D4mbTFY1.cjs → package.cjs} +22 -7
- package/dist/package.cjs.map +1 -0
- package/dist/{package-B0vvsKXO.mjs → package.mjs} +22 -5
- package/dist/package.mjs.map +1 -0
- package/dist/plugin.cjs +48 -0
- package/dist/plugin.cjs.map +1 -0
- package/dist/plugin.d.cts +62 -0
- package/dist/plugin.d.cts.map +1 -0
- package/dist/plugin.d.mts +62 -0
- package/dist/plugin.d.mts.map +1 -0
- package/dist/plugin.mjs +47 -0
- package/dist/plugin.mjs.map +1 -0
- package/dist/runtime/errors.cjs +45 -0
- package/dist/runtime/errors.cjs.map +1 -0
- package/dist/runtime/errors.d.cts +27 -0
- package/dist/runtime/errors.d.cts.map +1 -0
- package/dist/runtime/errors.d.mts +27 -0
- package/dist/runtime/errors.d.mts.map +1 -0
- package/dist/runtime/errors.mjs +41 -0
- package/dist/runtime/errors.mjs.map +1 -0
- package/dist/runtime/index.cjs +157 -5
- package/dist/runtime/index.cjs.map +1 -0
- package/dist/runtime/index.d.cts +43 -5
- package/dist/runtime/index.d.cts.map +1 -0
- package/dist/runtime/index.d.mts +43 -5
- package/dist/runtime/index.d.mts.map +1 -0
- package/dist/runtime/index.mjs +155 -4
- package/dist/runtime/index.mjs.map +1 -0
- package/dist/runtime/services/module-federation.service.cjs +143 -0
- package/dist/runtime/services/module-federation.service.cjs.map +1 -0
- package/dist/runtime/services/module-federation.service.d.cts +15 -0
- package/dist/runtime/services/module-federation.service.d.cts.map +1 -0
- package/dist/runtime/services/module-federation.service.d.mts +15 -0
- package/dist/runtime/services/module-federation.service.d.mts.map +1 -0
- package/dist/runtime/services/module-federation.service.mjs +143 -0
- package/dist/runtime/services/module-federation.service.mjs.map +1 -0
- package/dist/runtime/services/normalize.cjs +22 -2
- package/dist/runtime/services/normalize.cjs.map +1 -0
- package/dist/runtime/services/normalize.d.cts +21 -2
- package/dist/runtime/services/normalize.d.cts.map +1 -0
- package/dist/runtime/services/normalize.d.mts +21 -2
- package/dist/runtime/services/normalize.d.mts.map +1 -0
- package/dist/runtime/services/normalize.mjs +21 -2
- package/dist/runtime/services/normalize.mjs.map +1 -0
- package/dist/runtime/services/plugin-lifecycle.service.cjs +33 -0
- package/dist/runtime/services/plugin-lifecycle.service.cjs.map +1 -0
- package/dist/runtime/services/plugin-lifecycle.service.d.cts +17 -0
- package/dist/runtime/services/plugin-lifecycle.service.d.cts.map +1 -0
- package/dist/runtime/services/plugin-lifecycle.service.d.mts +17 -0
- package/dist/runtime/services/plugin-lifecycle.service.d.mts.map +1 -0
- package/dist/runtime/services/plugin-lifecycle.service.mjs +32 -0
- package/dist/runtime/services/plugin-lifecycle.service.mjs.map +1 -0
- package/dist/runtime/services/plugin-loader.service.cjs +125 -0
- package/dist/runtime/services/plugin-loader.service.cjs.map +1 -0
- package/dist/runtime/services/plugin-loader.service.d.cts +54 -0
- package/dist/runtime/services/plugin-loader.service.d.cts.map +1 -0
- package/dist/runtime/services/plugin-loader.service.d.mts +54 -0
- package/dist/runtime/services/plugin-loader.service.d.mts.map +1 -0
- package/dist/runtime/services/plugin-loader.service.mjs +121 -0
- package/dist/runtime/services/plugin-loader.service.mjs.map +1 -0
- package/dist/runtime/services/plugin.service.cjs +33 -0
- package/dist/runtime/services/plugin.service.cjs.map +1 -0
- package/dist/runtime/services/plugin.service.d.cts +42 -0
- package/dist/runtime/services/plugin.service.d.cts.map +1 -0
- package/dist/runtime/services/plugin.service.d.mts +42 -0
- package/dist/runtime/services/plugin.service.d.mts.map +1 -0
- package/dist/runtime/services/plugin.service.mjs +32 -0
- package/dist/runtime/services/plugin.service.mjs.map +1 -0
- package/dist/runtime/services/secrets.service.cjs +50 -0
- package/dist/runtime/services/secrets.service.cjs.map +1 -0
- package/dist/runtime/services/secrets.service.d.cts +16 -0
- package/dist/runtime/services/secrets.service.d.cts.map +1 -0
- package/dist/runtime/services/secrets.service.d.mts +16 -0
- package/dist/runtime/services/secrets.service.d.mts.map +1 -0
- package/dist/runtime/services/secrets.service.mjs +48 -0
- package/dist/runtime/services/secrets.service.mjs.map +1 -0
- package/dist/runtime/validation.cjs +18 -0
- package/dist/runtime/validation.cjs.map +1 -0
- package/dist/runtime/validation.mjs +17 -0
- package/dist/runtime/validation.mjs.map +1 -0
- package/dist/testing/index.cjs +33 -55
- package/dist/testing/index.cjs.map +1 -1
- package/dist/testing/index.d.cts +28 -33
- package/dist/testing/index.d.cts.map +1 -1
- package/dist/testing/index.d.mts +28 -33
- package/dist/testing/index.d.mts.map +1 -1
- package/dist/testing/index.mjs +34 -54
- package/dist/testing/index.mjs.map +1 -1
- package/dist/types.cjs +0 -0
- package/dist/types.d.cts +261 -0
- package/dist/types.d.cts.map +1 -0
- package/dist/types.d.mts +261 -0
- package/dist/types.d.mts.map +1 -0
- package/dist/types.mjs +1 -0
- package/dist/zod-core.cjs +9 -0
- package/dist/zod-core.d.cts +1 -0
- package/dist/zod-core.d.mts +1 -0
- package/dist/zod-core.mjs +3 -0
- package/dist/zod.cjs +13 -1
- package/dist/zod.cjs.map +1 -0
- package/dist/zod.d.cts +8 -2
- package/dist/zod.d.cts.map +1 -0
- package/dist/zod.d.mts +8 -2
- package/dist/zod.d.mts.map +1 -0
- package/dist/zod.mjs +9 -2
- package/dist/zod.mjs.map +1 -0
- package/package.json +17 -2
- package/dist/build/rspack/index.cjs.map +0 -1
- package/dist/build/rspack/index.d.cts.map +0 -1
- package/dist/build/rspack/index.d.mts.map +0 -1
- package/dist/build/rspack/index.mjs.map +0 -1
- package/dist/errors-9sNpYLv5.d.mts +0 -75
- package/dist/errors-9sNpYLv5.d.mts.map +0 -1
- package/dist/errors-CVnoPl9v.cjs +0 -68
- package/dist/errors-CVnoPl9v.cjs.map +0 -1
- package/dist/errors-D7keKf7a.mjs +0 -63
- package/dist/errors-D7keKf7a.mjs.map +0 -1
- package/dist/errors-DKPPPYYT.d.cts +0 -75
- package/dist/errors-DKPPPYYT.d.cts.map +0 -1
- package/dist/fetch-8DauUFDh.mjs +0 -335
- package/dist/fetch-8DauUFDh.mjs.map +0 -1
- package/dist/fetch-CrBvwsZ4.cjs +0 -336
- package/dist/fetch-CrBvwsZ4.cjs.map +0 -1
- package/dist/index-Coz54d1B.d.mts +0 -387
- package/dist/index-Coz54d1B.d.mts.map +0 -1
- package/dist/index-G63gBZIY.d.cts +0 -386
- package/dist/index-G63gBZIY.d.cts.map +0 -1
- package/dist/index.cjs.map +0 -1
- package/dist/index.mjs.map +0 -1
- package/dist/normalize-BW7kk8Lk.d.cts +0 -21
- package/dist/normalize-BW7kk8Lk.d.cts.map +0 -1
- package/dist/normalize-D4Qh0wVk.cjs +0 -28
- package/dist/normalize-D4Qh0wVk.cjs.map +0 -1
- package/dist/normalize-D7nae0Hn.mjs +0 -22
- package/dist/normalize-D7nae0Hn.mjs.map +0 -1
- package/dist/normalize-eB_j86fm.d.mts +0 -21
- package/dist/normalize-eB_j86fm.d.mts.map +0 -1
- package/dist/package-B0vvsKXO.mjs.map +0 -1
- package/dist/package-D4mbTFY1.cjs.map +0 -1
- package/dist/plugins-C6MGKdD-.mjs +0 -790
- package/dist/plugins-C6MGKdD-.mjs.map +0 -1
- package/dist/plugins-DNaNtkG7.cjs +0 -791
- package/dist/plugins-DNaNtkG7.cjs.map +0 -1
- package/dist/runtime-BTFJzoBu.cjs +0 -541
- package/dist/runtime-BTFJzoBu.cjs.map +0 -1
- package/dist/runtime-BYDchBFq.mjs +0 -476
- package/dist/runtime-BYDchBFq.mjs.map +0 -1
- package/dist/standard-CkH8zNkx.mjs +0 -584
- package/dist/standard-CkH8zNkx.mjs.map +0 -1
- package/dist/standard-v75BC6Z5.cjs +0 -685
- package/dist/standard-v75BC6Z5.cjs.map +0 -1
- package/dist/zod-A7Pti5IV.d.cts +0 -4
- package/dist/zod-A7Pti5IV.d.cts.map +0 -1
- package/dist/zod-BVo51kgJ.mjs +0 -10
- package/dist/zod-BVo51kgJ.mjs.map +0 -1
- package/dist/zod-DYghWCz1.cjs +0 -14
- package/dist/zod-DYghWCz1.cjs.map +0 -1
- package/dist/zod-Zw8dlP3j.d.mts +0 -4
- package/dist/zod-Zw8dlP3j.d.mts.map +0 -1
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_errors = require('../errors.cjs');
|
|
3
|
+
const require_runtime_services_normalize = require('./normalize.cjs');
|
|
4
|
+
const require_package$1 = require('../../package.cjs');
|
|
5
|
+
let effect = require("effect");
|
|
6
|
+
let __module_federation_enhanced_runtime = require("@module-federation/enhanced/runtime");
|
|
7
|
+
let __module_federation_runtime_core = require("@module-federation/runtime-core");
|
|
8
|
+
|
|
9
|
+
//#region src/runtime/services/module-federation.service.ts
|
|
10
|
+
var import_package = /* @__PURE__ */ require_rolldown_runtime.__toESM(require_package$1.default, 1);
|
|
11
|
+
const createModuleFederationInstance = effect.Effect.cached(effect.Effect.sync(() => {
|
|
12
|
+
try {
|
|
13
|
+
let instance = (0, __module_federation_enhanced_runtime.getInstance)();
|
|
14
|
+
if (!instance) {
|
|
15
|
+
instance = (0, __module_federation_enhanced_runtime.createInstance)({
|
|
16
|
+
name: "host",
|
|
17
|
+
remotes: [],
|
|
18
|
+
shared: {
|
|
19
|
+
"every-plugin": {
|
|
20
|
+
version: import_package.default.version,
|
|
21
|
+
shareConfig: {
|
|
22
|
+
singleton: true,
|
|
23
|
+
requiredVersion: `^${import_package.default.version}`,
|
|
24
|
+
eager: true,
|
|
25
|
+
strictVersion: false
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
effect: {
|
|
29
|
+
version: import_package.default.dependencies.effect,
|
|
30
|
+
shareConfig: {
|
|
31
|
+
singleton: true,
|
|
32
|
+
requiredVersion: "^3.18.0",
|
|
33
|
+
eager: true,
|
|
34
|
+
strictVersion: false
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
zod: {
|
|
38
|
+
version: import_package.default.dependencies.zod,
|
|
39
|
+
shareConfig: {
|
|
40
|
+
singleton: true,
|
|
41
|
+
requiredVersion: "^4.1.0",
|
|
42
|
+
eager: true,
|
|
43
|
+
strictVersion: false
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"@orpc/contract": {
|
|
47
|
+
version: import_package.default.dependencies["@orpc/contract"],
|
|
48
|
+
shareConfig: {
|
|
49
|
+
singleton: true,
|
|
50
|
+
requiredVersion: "^1.8.0",
|
|
51
|
+
eager: true,
|
|
52
|
+
strictVersion: false
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"@orpc/server": {
|
|
56
|
+
version: import_package.default.dependencies["@orpc/server"],
|
|
57
|
+
shareConfig: {
|
|
58
|
+
singleton: true,
|
|
59
|
+
requiredVersion: "^1.8.0",
|
|
60
|
+
eager: true,
|
|
61
|
+
strictVersion: false
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
(0, __module_federation_runtime_core.setGlobalFederationInstance)(instance);
|
|
67
|
+
}
|
|
68
|
+
return instance;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
throw new Error(`Failed to initialize Module Federation: ${error}`);
|
|
71
|
+
}
|
|
72
|
+
}));
|
|
73
|
+
var ModuleFederationService = class extends effect.Effect.Service()("ModuleFederationService", { effect: effect.Effect.gen(function* () {
|
|
74
|
+
const mf = yield* effect.Effect.flatten(createModuleFederationInstance);
|
|
75
|
+
return {
|
|
76
|
+
registerRemote: (pluginId, url) => effect.Effect.gen(function* () {
|
|
77
|
+
console.log(`[MF] Registering ${pluginId}`);
|
|
78
|
+
const manifestUrl = url.endsWith("/") ? `${url}mf-manifest.json` : `${url}/mf-manifest.json`;
|
|
79
|
+
const manifestCheck = yield* effect.Effect.tryPromise({
|
|
80
|
+
try: async () => {
|
|
81
|
+
return (await fetch(manifestUrl, { method: "HEAD" })).ok;
|
|
82
|
+
},
|
|
83
|
+
catch: () => false
|
|
84
|
+
});
|
|
85
|
+
let entryUrl;
|
|
86
|
+
let isManifestMode = false;
|
|
87
|
+
if (manifestCheck) {
|
|
88
|
+
entryUrl = manifestUrl;
|
|
89
|
+
isManifestMode = true;
|
|
90
|
+
console.log(`[MF] Using MF 2.0 manifest mode for ${pluginId}`);
|
|
91
|
+
} else {
|
|
92
|
+
console.log(`[MF] ⚠️ Manifest not found, falling back to MF 1.5 mode for ${pluginId}`);
|
|
93
|
+
entryUrl = url;
|
|
94
|
+
isManifestMode = false;
|
|
95
|
+
}
|
|
96
|
+
const remoteName = isManifestMode ? pluginId : require_runtime_services_normalize.getNormalizedRemoteName(pluginId);
|
|
97
|
+
yield* effect.Effect.try({
|
|
98
|
+
try: () => mf.registerRemotes([{
|
|
99
|
+
name: remoteName,
|
|
100
|
+
entry: entryUrl,
|
|
101
|
+
...isManifestMode && { alias: pluginId }
|
|
102
|
+
}]),
|
|
103
|
+
catch: (error) => new require_errors.ModuleFederationError({
|
|
104
|
+
pluginId,
|
|
105
|
+
remoteUrl: url,
|
|
106
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
console.log(`[MF] ✅ Registered ${pluginId} (${isManifestMode ? "MF 2.0" : "MF 1.5"})`);
|
|
110
|
+
}),
|
|
111
|
+
loadRemoteConstructor: (pluginId, url) => effect.Effect.gen(function* () {
|
|
112
|
+
const remoteName = require_runtime_services_normalize.getNormalizedRemoteName(pluginId);
|
|
113
|
+
console.log(`[MF] Loading remote ${remoteName}`);
|
|
114
|
+
const modulePath = `${remoteName}/plugin`;
|
|
115
|
+
return yield* effect.Effect.tryPromise({
|
|
116
|
+
try: async () => {
|
|
117
|
+
const container = await mf.loadRemote(modulePath);
|
|
118
|
+
if (!container) throw new Error(`No container returned for ${modulePath}`);
|
|
119
|
+
const Constructor = typeof container === "function" ? container : container.default ? container.default : Object.values(container).find((exp) => typeof exp === "function" && exp.prototype?.constructor === exp);
|
|
120
|
+
if (!Constructor || typeof Constructor !== "function") {
|
|
121
|
+
const containerInfo = typeof container === "object" ? `Available exports: ${Object.keys(container).join(", ")}` : `Container type: ${typeof container}`;
|
|
122
|
+
throw new Error(`No valid plugin constructor found for '${pluginId}'.\nSupported patterns:\n - export const YourPlugin = createPlugin({...})\n - export default createPlugin({...})\n${containerInfo}`);
|
|
123
|
+
}
|
|
124
|
+
if (!Constructor.binding) {
|
|
125
|
+
const containerInfo = typeof container === "object" ? `Found exports: ${Object.keys(container).join(", ")}` : `Container type: ${typeof container}`;
|
|
126
|
+
throw new Error(`Invalid plugin constructor for '${pluginId}'. The exported value must be created with createPlugin(). Found a function but it's missing the required 'binding' property.\n${containerInfo}`);
|
|
127
|
+
}
|
|
128
|
+
console.log(`[MF] ✅ Loaded constructor for ${pluginId}`);
|
|
129
|
+
return Constructor;
|
|
130
|
+
},
|
|
131
|
+
catch: (error) => new require_errors.ModuleFederationError({
|
|
132
|
+
pluginId,
|
|
133
|
+
remoteUrl: url,
|
|
134
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
})
|
|
138
|
+
};
|
|
139
|
+
}) }) {};
|
|
140
|
+
|
|
141
|
+
//#endregion
|
|
142
|
+
exports.ModuleFederationService = ModuleFederationService;
|
|
143
|
+
//# sourceMappingURL=module-federation.service.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-federation.service.cjs","names":["Effect","pkg","entryUrl: string","getNormalizedRemoteName","ModuleFederationError"],"sources":["../../../src/runtime/services/module-federation.service.ts"],"sourcesContent":["import {\n\tcreateInstance,\n\tgetInstance,\n} from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { Effect } from \"effect\";\nimport type { AnyPlugin } from \"../../types\";\nimport { ModuleFederationError } from \"../errors\";\nimport { getNormalizedRemoteName } from \"./normalize\";\n\ntype RemoteModule = \n | (new () => AnyPlugin)\n | { default: new () => AnyPlugin };\n\nimport pkg from \"../../../package.json\";\n\nconst createModuleFederationInstance = Effect.cached(\n\tEffect.sync(() => {\n\t\ttry {\n\t\t\tlet instance = getInstance();\n\n\t\t\tif (!instance) {\n\t\t\t\tinstance = createInstance({\n\t\t\t\t\tname: \"host\",\n\t\t\t\t\tremotes: [],\n\t\t\t\t\tshared: {\n\t\t\t\t\t\t\"every-plugin\": {\n\t\t\t\t\t\t\tversion: pkg.version,\n\t\t\t\t\t\t\tshareConfig: {\n\t\t\t\t\t\t\t\tsingleton: true,\n\t\t\t\t\t\t\t\trequiredVersion: `^${pkg.version}`,\n\t\t\t\t\t\t\t\teager: true,\n\t\t\t\t\t\t\t\tstrictVersion: false, // Allow bidirectional version compatibility\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\teffect: {\n\t\t\t\t\t\t\tversion: pkg.dependencies.effect,\n\t\t\t\t\t\t\tshareConfig: {\n\t\t\t\t\t\t\t\tsingleton: true,\n\t\t\t\t\t\t\t\trequiredVersion: \"^3.18.0\", // Allow any 3.18.x patch version\n\t\t\t\t\t\t\t\teager: true,\n\t\t\t\t\t\t\t\tstrictVersion: false, // Allow version flexibility for compatibility\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tzod: {\n\t\t\t\t\t\t\tversion: pkg.dependencies.zod,\n\t\t\t\t\t\t\tshareConfig: {\n\t\t\t\t\t\t\t\tsingleton: true,\n\t\t\t\t\t\t\t\trequiredVersion: \"^4.1.0\", // Allow any 4.1.x patch version\n\t\t\t\t\t\t\t\teager: true,\n\t\t\t\t\t\t\t\tstrictVersion: false, // Allow version flexibility for compatibility\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"@orpc/contract\": {\n\t\t\t\t\t\t\tversion: pkg.dependencies[\"@orpc/contract\"],\n\t\t\t\t\t\t\tshareConfig: {\n\t\t\t\t\t\t\t\tsingleton: true,\n\t\t\t\t\t\t\t\trequiredVersion: \"^1.8.0\", // Allow any 1.8.x patch version\n\t\t\t\t\t\t\t\teager: true,\n\t\t\t\t\t\t\t\tstrictVersion: false, // Allow version flexibility for compatibility\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"@orpc/server\": {\n\t\t\t\t\t\t\tversion: pkg.dependencies[\"@orpc/server\"],\n\t\t\t\t\t\t\tshareConfig: {\n\t\t\t\t\t\t\t\tsingleton: true,\n\t\t\t\t\t\t\t\trequiredVersion: \"^1.8.0\", // Allow any 1.8.x patch version\n\t\t\t\t\t\t\t\teager: true,\n\t\t\t\t\t\t\t\tstrictVersion: false, // Allow version flexibility for compatibility\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tsetGlobalFederationInstance(instance);\n\t\t\t}\n\n\t\t\treturn instance;\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to initialize Module Federation: ${error}`);\n\t\t}\n\t}),\n);\n\nexport class ModuleFederationService extends Effect.Service<ModuleFederationService>()(\"ModuleFederationService\", {\n\teffect: Effect.gen(function* () {\n\t\tconst mf = yield* Effect.flatten(createModuleFederationInstance);\n\n\t\treturn {\n\t\t\tregisterRemote: (pluginId: string, url: string) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tconsole.log(`[MF] Registering ${pluginId}`);\n\n\t\t\t\t\tconst manifestUrl = url.endsWith('/')\n\t\t\t\t\t\t? `${url}mf-manifest.json`\n\t\t\t\t\t\t: `${url}/mf-manifest.json`;\n\n\t\t\t\t\t// Check if manifest is available (MF 2.0 with manifests)\n\t\t\t\t\tconst manifestCheck = yield* Effect.tryPromise({\n\t\t\t\t\t\ttry: async () => {\n\t\t\t\t\t\t\tconst response = await fetch(manifestUrl, { method: \"HEAD\" });\n\t\t\t\t\t\t\treturn response.ok;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcatch: () => false,\n\t\t\t\t\t});\n\n\t\t\t\t\tlet entryUrl: string;\n\t\t\t\t\tlet isManifestMode = false;\n\n\t\t\t\t\tif (manifestCheck) {\n\t\t\t\t\t\t// MF 2.0 manifest mode - use manifest URL\n\t\t\t\t\t\tentryUrl = manifestUrl;\n\t\t\t\t\t\tisManifestMode = true;\n\t\t\t\t\t\tconsole.log(`[MF] Using MF 2.0 manifest mode for ${pluginId}`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Fallback to MF 1.5 direct mode - assume URL points to remoteEntry.js\n\t\t\t\t\t\tconsole.log(`[MF] ⚠️ Manifest not found, falling back to MF 1.5 mode for ${pluginId}`);\n\t\t\t\t\t\tentryUrl = url;\n\t\t\t\t\t\tisManifestMode = false;\n\t\t\t\t\t}\n\n\t\t\t\t\t// For MF 2.0, the name can be the pluginId (alias)\n\t\t\t\t\t// The manifest will contain the actual container name\n\t\t\t\t\tconst remoteName = isManifestMode ? pluginId : getNormalizedRemoteName(pluginId);\n\n\t\t\t\t\tyield* Effect.try({\n\t\t\t\t\t\ttry: () => mf.registerRemotes([{\n\t\t\t\t\t\t\tname: remoteName,\n\t\t\t\t\t\t\tentry: entryUrl,\n\t\t\t\t\t\t\t...(isManifestMode && { alias: pluginId }) // Explicit alias for clarity\n\t\t\t\t\t\t}]),\n\t\t\t\t\t\tcatch: (error): ModuleFederationError =>\n\t\t\t\t\t\t\tnew ModuleFederationError({\n\t\t\t\t\t\t\t\tpluginId,\n\t\t\t\t\t\t\t\tremoteUrl: url,\n\t\t\t\t\t\t\t\tcause:\n\t\t\t\t\t\t\t\t\terror instanceof Error ? error : new Error(String(error)),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\n\t\t\t\t\tconsole.log(`[MF] ✅ Registered ${pluginId} (${isManifestMode ? 'MF 2.0' : 'MF 1.5'})`);\n\t\t\t\t}),\n\n\t\t\tloadRemoteConstructor: (pluginId: string, url: string) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tconst remoteName = getNormalizedRemoteName(pluginId);\n\t\t\t\t\tconsole.log(`[MF] Loading remote ${remoteName}`);\n\t\t\t\t\tconst modulePath = `${remoteName}/plugin`;\n\n\t\t\t\t\treturn yield* Effect.tryPromise({\n\t\t\t\t\t\ttry: async () => {\n\n\t\t\t\t\t\t\tconst container = await mf.loadRemote<RemoteModule>(modulePath);\n\t\t\t\t\t\t\tif (!container) {\n\t\t\t\t\t\t\t\tthrow new Error(`No container returned for ${modulePath}`);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Support multiple export patterns: direct function, default export, named exports\n\t\t\t\t\t\t\tconst Constructor =\n\t\t\t\t\t\t\t\ttypeof container === \"function\"\n\t\t\t\t\t\t\t\t\t? container // Direct function export\n\t\t\t\t\t\t\t\t\t: container.default\n\t\t\t\t\t\t\t\t\t? container.default // Default export\n\t\t\t\t\t\t\t\t\t: Object.values(container).find( // Named export fallback\n\t\t\t\t\t\t\t\t\t\t\t(exp) => typeof exp === \"function\" && exp.prototype?.constructor === exp\n\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (!Constructor || typeof Constructor !== \"function\") {\n\t\t\t\t\t\t\t\tconst containerInfo = typeof container === \"object\"\n\t\t\t\t\t\t\t\t\t? `Available exports: ${Object.keys(container).join(', ')}`\n\t\t\t\t\t\t\t\t\t: `Container type: ${typeof container}`;\n\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t`No valid plugin constructor found for '${pluginId}'.\\n` +\n\t\t\t\t\t\t\t\t\t`Supported patterns:\\n` +\n\t\t\t\t\t\t\t\t\t` - export const YourPlugin = createPlugin({...})\\n` +\n\t\t\t\t\t\t\t\t\t` - export default createPlugin({...})\\n` +\n\t\t\t\t\t\t\t\t\t`${containerInfo}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Validate it looks like a plugin constructor (has binding property)\n\t\t\t\t\t\t\tif (!(Constructor as any).binding) {\n\t\t\t\t\t\t\t\tconst containerInfo = typeof container === \"object\"\n\t\t\t\t\t\t\t\t\t? `Found exports: ${Object.keys(container).join(', ')}`\n\t\t\t\t\t\t\t\t\t: `Container type: ${typeof container}`;\n\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t`Invalid plugin constructor for '${pluginId}'. ` +\n\t\t\t\t\t\t\t\t\t`The exported value must be created with createPlugin(). ` +\n\t\t\t\t\t\t\t\t\t`Found a function but it's missing the required 'binding' property.\\n` +\n\t\t\t\t\t\t\t\t\t`${containerInfo}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconsole.log(`[MF] ✅ Loaded constructor for ${pluginId}`);\n\t\t\t\t\t\t\treturn Constructor;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcatch: (error): ModuleFederationError =>\n\t\t\t\t\t\t\tnew ModuleFederationError({\n\t\t\t\t\t\t\t\tpluginId,\n\t\t\t\t\t\t\t\tremoteUrl: url,\n\t\t\t\t\t\t\t\tcause:\n\t\t\t\t\t\t\t\t\terror instanceof Error ? error : new Error(String(error)),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}),\n\t\t};\n\t}),\n}) {}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AnyPlugin } from "../../types.cjs";
|
|
2
|
+
import { ModuleFederationError } from "../errors.cjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/runtime/services/module-federation.service.d.ts
|
|
6
|
+
declare const ModuleFederationService_base: Effect.Service.Class<ModuleFederationService, "ModuleFederationService", {
|
|
7
|
+
readonly effect: Effect.Effect<{
|
|
8
|
+
registerRemote: (pluginId: string, url: string) => Effect.Effect<void, boolean | ModuleFederationError, never>;
|
|
9
|
+
loadRemoteConstructor: (pluginId: string, url: string) => Effect.Effect<new () => AnyPlugin, ModuleFederationError, never>;
|
|
10
|
+
}, never, never>;
|
|
11
|
+
}>;
|
|
12
|
+
declare class ModuleFederationService extends ModuleFederationService_base {}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { ModuleFederationService };
|
|
15
|
+
//# sourceMappingURL=module-federation.service.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-federation.service.d.cts","names":[],"sources":["../../../src/runtime/services/module-federation.service.ts"],"sourcesContent":[],"mappings":";;;;;cAOkD;;IAAA,cAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,GAAA,EAAA,MAAA,EAAA,GAkFD,MAAA,CAAA,MAlFC,CAAA,IAAA,EAAA,OAAA,GAkFD,qBAlFC,EAAA,KAAA,CAAA;8DAwIM,MAAA,CAAA,iBApIzC,WAAS;EA8EyB,CAAA,EAAA,KAAA,EAAA,KAAA,CAAA;CAAA,CAAA;AA9ElC,cAyEF,uBAAA,SAAgC,4BAAA,CAzE9B"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { AnyPlugin } from "../../types.mjs";
|
|
2
|
+
import { ModuleFederationError } from "../errors.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/runtime/services/module-federation.service.d.ts
|
|
6
|
+
declare const ModuleFederationService_base: Effect.Service.Class<ModuleFederationService, "ModuleFederationService", {
|
|
7
|
+
readonly effect: Effect.Effect<{
|
|
8
|
+
registerRemote: (pluginId: string, url: string) => Effect.Effect<void, boolean | ModuleFederationError, never>;
|
|
9
|
+
loadRemoteConstructor: (pluginId: string, url: string) => Effect.Effect<new () => AnyPlugin, ModuleFederationError, never>;
|
|
10
|
+
}, never, never>;
|
|
11
|
+
}>;
|
|
12
|
+
declare class ModuleFederationService extends ModuleFederationService_base {}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { ModuleFederationService };
|
|
15
|
+
//# sourceMappingURL=module-federation.service.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-federation.service.d.mts","names":[],"sources":["../../../src/runtime/services/module-federation.service.ts"],"sourcesContent":[],"mappings":";;;;;cAOkD;;IAAA,cAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,GAAA,EAAA,MAAA,EAAA,GAkFD,MAAA,CAAA,MAlFC,CAAA,IAAA,EAAA,OAAA,GAkFD,qBAlFC,EAAA,KAAA,CAAA;8DAwIM,MAAA,CAAA,iBApIzC,WAAS;EA8EyB,CAAA,EAAA,KAAA,EAAA,KAAA,CAAA;CAAA,CAAA;AA9ElC,cAyEF,uBAAA,SAAgC,4BAAA,CAzE9B"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { __toESM } from "../../_virtual/rolldown_runtime.mjs";
|
|
2
|
+
import { ModuleFederationError } from "../errors.mjs";
|
|
3
|
+
import { getNormalizedRemoteName } from "./normalize.mjs";
|
|
4
|
+
import { require_package } from "../../package.mjs";
|
|
5
|
+
import { Effect } from "effect";
|
|
6
|
+
import { createInstance, getInstance } from "@module-federation/enhanced/runtime";
|
|
7
|
+
import { setGlobalFederationInstance } from "@module-federation/runtime-core";
|
|
8
|
+
|
|
9
|
+
//#region src/runtime/services/module-federation.service.ts
|
|
10
|
+
var import_package = /* @__PURE__ */ __toESM(require_package(), 1);
|
|
11
|
+
const createModuleFederationInstance = Effect.cached(Effect.sync(() => {
|
|
12
|
+
try {
|
|
13
|
+
let instance = getInstance();
|
|
14
|
+
if (!instance) {
|
|
15
|
+
instance = createInstance({
|
|
16
|
+
name: "host",
|
|
17
|
+
remotes: [],
|
|
18
|
+
shared: {
|
|
19
|
+
"every-plugin": {
|
|
20
|
+
version: import_package.default.version,
|
|
21
|
+
shareConfig: {
|
|
22
|
+
singleton: true,
|
|
23
|
+
requiredVersion: `^${import_package.default.version}`,
|
|
24
|
+
eager: true,
|
|
25
|
+
strictVersion: false
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
effect: {
|
|
29
|
+
version: import_package.default.dependencies.effect,
|
|
30
|
+
shareConfig: {
|
|
31
|
+
singleton: true,
|
|
32
|
+
requiredVersion: "^3.18.0",
|
|
33
|
+
eager: true,
|
|
34
|
+
strictVersion: false
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
zod: {
|
|
38
|
+
version: import_package.default.dependencies.zod,
|
|
39
|
+
shareConfig: {
|
|
40
|
+
singleton: true,
|
|
41
|
+
requiredVersion: "^4.1.0",
|
|
42
|
+
eager: true,
|
|
43
|
+
strictVersion: false
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"@orpc/contract": {
|
|
47
|
+
version: import_package.default.dependencies["@orpc/contract"],
|
|
48
|
+
shareConfig: {
|
|
49
|
+
singleton: true,
|
|
50
|
+
requiredVersion: "^1.8.0",
|
|
51
|
+
eager: true,
|
|
52
|
+
strictVersion: false
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"@orpc/server": {
|
|
56
|
+
version: import_package.default.dependencies["@orpc/server"],
|
|
57
|
+
shareConfig: {
|
|
58
|
+
singleton: true,
|
|
59
|
+
requiredVersion: "^1.8.0",
|
|
60
|
+
eager: true,
|
|
61
|
+
strictVersion: false
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
setGlobalFederationInstance(instance);
|
|
67
|
+
}
|
|
68
|
+
return instance;
|
|
69
|
+
} catch (error) {
|
|
70
|
+
throw new Error(`Failed to initialize Module Federation: ${error}`);
|
|
71
|
+
}
|
|
72
|
+
}));
|
|
73
|
+
var ModuleFederationService = class extends Effect.Service()("ModuleFederationService", { effect: Effect.gen(function* () {
|
|
74
|
+
const mf = yield* Effect.flatten(createModuleFederationInstance);
|
|
75
|
+
return {
|
|
76
|
+
registerRemote: (pluginId, url) => Effect.gen(function* () {
|
|
77
|
+
console.log(`[MF] Registering ${pluginId}`);
|
|
78
|
+
const manifestUrl = url.endsWith("/") ? `${url}mf-manifest.json` : `${url}/mf-manifest.json`;
|
|
79
|
+
const manifestCheck = yield* Effect.tryPromise({
|
|
80
|
+
try: async () => {
|
|
81
|
+
return (await fetch(manifestUrl, { method: "HEAD" })).ok;
|
|
82
|
+
},
|
|
83
|
+
catch: () => false
|
|
84
|
+
});
|
|
85
|
+
let entryUrl;
|
|
86
|
+
let isManifestMode = false;
|
|
87
|
+
if (manifestCheck) {
|
|
88
|
+
entryUrl = manifestUrl;
|
|
89
|
+
isManifestMode = true;
|
|
90
|
+
console.log(`[MF] Using MF 2.0 manifest mode for ${pluginId}`);
|
|
91
|
+
} else {
|
|
92
|
+
console.log(`[MF] ⚠️ Manifest not found, falling back to MF 1.5 mode for ${pluginId}`);
|
|
93
|
+
entryUrl = url;
|
|
94
|
+
isManifestMode = false;
|
|
95
|
+
}
|
|
96
|
+
const remoteName = isManifestMode ? pluginId : getNormalizedRemoteName(pluginId);
|
|
97
|
+
yield* Effect.try({
|
|
98
|
+
try: () => mf.registerRemotes([{
|
|
99
|
+
name: remoteName,
|
|
100
|
+
entry: entryUrl,
|
|
101
|
+
...isManifestMode && { alias: pluginId }
|
|
102
|
+
}]),
|
|
103
|
+
catch: (error) => new ModuleFederationError({
|
|
104
|
+
pluginId,
|
|
105
|
+
remoteUrl: url,
|
|
106
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
107
|
+
})
|
|
108
|
+
});
|
|
109
|
+
console.log(`[MF] ✅ Registered ${pluginId} (${isManifestMode ? "MF 2.0" : "MF 1.5"})`);
|
|
110
|
+
}),
|
|
111
|
+
loadRemoteConstructor: (pluginId, url) => Effect.gen(function* () {
|
|
112
|
+
const remoteName = getNormalizedRemoteName(pluginId);
|
|
113
|
+
console.log(`[MF] Loading remote ${remoteName}`);
|
|
114
|
+
const modulePath = `${remoteName}/plugin`;
|
|
115
|
+
return yield* Effect.tryPromise({
|
|
116
|
+
try: async () => {
|
|
117
|
+
const container = await mf.loadRemote(modulePath);
|
|
118
|
+
if (!container) throw new Error(`No container returned for ${modulePath}`);
|
|
119
|
+
const Constructor = typeof container === "function" ? container : container.default ? container.default : Object.values(container).find((exp) => typeof exp === "function" && exp.prototype?.constructor === exp);
|
|
120
|
+
if (!Constructor || typeof Constructor !== "function") {
|
|
121
|
+
const containerInfo = typeof container === "object" ? `Available exports: ${Object.keys(container).join(", ")}` : `Container type: ${typeof container}`;
|
|
122
|
+
throw new Error(`No valid plugin constructor found for '${pluginId}'.\nSupported patterns:\n - export const YourPlugin = createPlugin({...})\n - export default createPlugin({...})\n${containerInfo}`);
|
|
123
|
+
}
|
|
124
|
+
if (!Constructor.binding) {
|
|
125
|
+
const containerInfo = typeof container === "object" ? `Found exports: ${Object.keys(container).join(", ")}` : `Container type: ${typeof container}`;
|
|
126
|
+
throw new Error(`Invalid plugin constructor for '${pluginId}'. The exported value must be created with createPlugin(). Found a function but it's missing the required 'binding' property.\n${containerInfo}`);
|
|
127
|
+
}
|
|
128
|
+
console.log(`[MF] ✅ Loaded constructor for ${pluginId}`);
|
|
129
|
+
return Constructor;
|
|
130
|
+
},
|
|
131
|
+
catch: (error) => new ModuleFederationError({
|
|
132
|
+
pluginId,
|
|
133
|
+
remoteUrl: url,
|
|
134
|
+
cause: error instanceof Error ? error : new Error(String(error))
|
|
135
|
+
})
|
|
136
|
+
});
|
|
137
|
+
})
|
|
138
|
+
};
|
|
139
|
+
}) }) {};
|
|
140
|
+
|
|
141
|
+
//#endregion
|
|
142
|
+
export { ModuleFederationService };
|
|
143
|
+
//# sourceMappingURL=module-federation.service.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-federation.service.mjs","names":["pkg","entryUrl: string"],"sources":["../../../src/runtime/services/module-federation.service.ts"],"sourcesContent":["import {\n\tcreateInstance,\n\tgetInstance,\n} from \"@module-federation/enhanced/runtime\";\nimport { setGlobalFederationInstance } from \"@module-federation/runtime-core\";\nimport { Effect } from \"effect\";\nimport type { AnyPlugin } from \"../../types\";\nimport { ModuleFederationError } from \"../errors\";\nimport { getNormalizedRemoteName } from \"./normalize\";\n\ntype RemoteModule = \n | (new () => AnyPlugin)\n | { default: new () => AnyPlugin };\n\nimport pkg from \"../../../package.json\";\n\nconst createModuleFederationInstance = Effect.cached(\n\tEffect.sync(() => {\n\t\ttry {\n\t\t\tlet instance = getInstance();\n\n\t\t\tif (!instance) {\n\t\t\t\tinstance = createInstance({\n\t\t\t\t\tname: \"host\",\n\t\t\t\t\tremotes: [],\n\t\t\t\t\tshared: {\n\t\t\t\t\t\t\"every-plugin\": {\n\t\t\t\t\t\t\tversion: pkg.version,\n\t\t\t\t\t\t\tshareConfig: {\n\t\t\t\t\t\t\t\tsingleton: true,\n\t\t\t\t\t\t\t\trequiredVersion: `^${pkg.version}`,\n\t\t\t\t\t\t\t\teager: true,\n\t\t\t\t\t\t\t\tstrictVersion: false, // Allow bidirectional version compatibility\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\teffect: {\n\t\t\t\t\t\t\tversion: pkg.dependencies.effect,\n\t\t\t\t\t\t\tshareConfig: {\n\t\t\t\t\t\t\t\tsingleton: true,\n\t\t\t\t\t\t\t\trequiredVersion: \"^3.18.0\", // Allow any 3.18.x patch version\n\t\t\t\t\t\t\t\teager: true,\n\t\t\t\t\t\t\t\tstrictVersion: false, // Allow version flexibility for compatibility\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tzod: {\n\t\t\t\t\t\t\tversion: pkg.dependencies.zod,\n\t\t\t\t\t\t\tshareConfig: {\n\t\t\t\t\t\t\t\tsingleton: true,\n\t\t\t\t\t\t\t\trequiredVersion: \"^4.1.0\", // Allow any 4.1.x patch version\n\t\t\t\t\t\t\t\teager: true,\n\t\t\t\t\t\t\t\tstrictVersion: false, // Allow version flexibility for compatibility\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"@orpc/contract\": {\n\t\t\t\t\t\t\tversion: pkg.dependencies[\"@orpc/contract\"],\n\t\t\t\t\t\t\tshareConfig: {\n\t\t\t\t\t\t\t\tsingleton: true,\n\t\t\t\t\t\t\t\trequiredVersion: \"^1.8.0\", // Allow any 1.8.x patch version\n\t\t\t\t\t\t\t\teager: true,\n\t\t\t\t\t\t\t\tstrictVersion: false, // Allow version flexibility for compatibility\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"@orpc/server\": {\n\t\t\t\t\t\t\tversion: pkg.dependencies[\"@orpc/server\"],\n\t\t\t\t\t\t\tshareConfig: {\n\t\t\t\t\t\t\t\tsingleton: true,\n\t\t\t\t\t\t\t\trequiredVersion: \"^1.8.0\", // Allow any 1.8.x patch version\n\t\t\t\t\t\t\t\teager: true,\n\t\t\t\t\t\t\t\tstrictVersion: false, // Allow version flexibility for compatibility\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tsetGlobalFederationInstance(instance);\n\t\t\t}\n\n\t\t\treturn instance;\n\t\t} catch (error) {\n\t\t\tthrow new Error(`Failed to initialize Module Federation: ${error}`);\n\t\t}\n\t}),\n);\n\nexport class ModuleFederationService extends Effect.Service<ModuleFederationService>()(\"ModuleFederationService\", {\n\teffect: Effect.gen(function* () {\n\t\tconst mf = yield* Effect.flatten(createModuleFederationInstance);\n\n\t\treturn {\n\t\t\tregisterRemote: (pluginId: string, url: string) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tconsole.log(`[MF] Registering ${pluginId}`);\n\n\t\t\t\t\tconst manifestUrl = url.endsWith('/')\n\t\t\t\t\t\t? `${url}mf-manifest.json`\n\t\t\t\t\t\t: `${url}/mf-manifest.json`;\n\n\t\t\t\t\t// Check if manifest is available (MF 2.0 with manifests)\n\t\t\t\t\tconst manifestCheck = yield* Effect.tryPromise({\n\t\t\t\t\t\ttry: async () => {\n\t\t\t\t\t\t\tconst response = await fetch(manifestUrl, { method: \"HEAD\" });\n\t\t\t\t\t\t\treturn response.ok;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcatch: () => false,\n\t\t\t\t\t});\n\n\t\t\t\t\tlet entryUrl: string;\n\t\t\t\t\tlet isManifestMode = false;\n\n\t\t\t\t\tif (manifestCheck) {\n\t\t\t\t\t\t// MF 2.0 manifest mode - use manifest URL\n\t\t\t\t\t\tentryUrl = manifestUrl;\n\t\t\t\t\t\tisManifestMode = true;\n\t\t\t\t\t\tconsole.log(`[MF] Using MF 2.0 manifest mode for ${pluginId}`);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Fallback to MF 1.5 direct mode - assume URL points to remoteEntry.js\n\t\t\t\t\t\tconsole.log(`[MF] ⚠️ Manifest not found, falling back to MF 1.5 mode for ${pluginId}`);\n\t\t\t\t\t\tentryUrl = url;\n\t\t\t\t\t\tisManifestMode = false;\n\t\t\t\t\t}\n\n\t\t\t\t\t// For MF 2.0, the name can be the pluginId (alias)\n\t\t\t\t\t// The manifest will contain the actual container name\n\t\t\t\t\tconst remoteName = isManifestMode ? pluginId : getNormalizedRemoteName(pluginId);\n\n\t\t\t\t\tyield* Effect.try({\n\t\t\t\t\t\ttry: () => mf.registerRemotes([{\n\t\t\t\t\t\t\tname: remoteName,\n\t\t\t\t\t\t\tentry: entryUrl,\n\t\t\t\t\t\t\t...(isManifestMode && { alias: pluginId }) // Explicit alias for clarity\n\t\t\t\t\t\t}]),\n\t\t\t\t\t\tcatch: (error): ModuleFederationError =>\n\t\t\t\t\t\t\tnew ModuleFederationError({\n\t\t\t\t\t\t\t\tpluginId,\n\t\t\t\t\t\t\t\tremoteUrl: url,\n\t\t\t\t\t\t\t\tcause:\n\t\t\t\t\t\t\t\t\terror instanceof Error ? error : new Error(String(error)),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\n\t\t\t\t\tconsole.log(`[MF] ✅ Registered ${pluginId} (${isManifestMode ? 'MF 2.0' : 'MF 1.5'})`);\n\t\t\t\t}),\n\n\t\t\tloadRemoteConstructor: (pluginId: string, url: string) =>\n\t\t\t\tEffect.gen(function* () {\n\t\t\t\t\tconst remoteName = getNormalizedRemoteName(pluginId);\n\t\t\t\t\tconsole.log(`[MF] Loading remote ${remoteName}`);\n\t\t\t\t\tconst modulePath = `${remoteName}/plugin`;\n\n\t\t\t\t\treturn yield* Effect.tryPromise({\n\t\t\t\t\t\ttry: async () => {\n\n\t\t\t\t\t\t\tconst container = await mf.loadRemote<RemoteModule>(modulePath);\n\t\t\t\t\t\t\tif (!container) {\n\t\t\t\t\t\t\t\tthrow new Error(`No container returned for ${modulePath}`);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Support multiple export patterns: direct function, default export, named exports\n\t\t\t\t\t\t\tconst Constructor =\n\t\t\t\t\t\t\t\ttypeof container === \"function\"\n\t\t\t\t\t\t\t\t\t? container // Direct function export\n\t\t\t\t\t\t\t\t\t: container.default\n\t\t\t\t\t\t\t\t\t? container.default // Default export\n\t\t\t\t\t\t\t\t\t: Object.values(container).find( // Named export fallback\n\t\t\t\t\t\t\t\t\t\t\t(exp) => typeof exp === \"function\" && exp.prototype?.constructor === exp\n\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (!Constructor || typeof Constructor !== \"function\") {\n\t\t\t\t\t\t\t\tconst containerInfo = typeof container === \"object\"\n\t\t\t\t\t\t\t\t\t? `Available exports: ${Object.keys(container).join(', ')}`\n\t\t\t\t\t\t\t\t\t: `Container type: ${typeof container}`;\n\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t`No valid plugin constructor found for '${pluginId}'.\\n` +\n\t\t\t\t\t\t\t\t\t`Supported patterns:\\n` +\n\t\t\t\t\t\t\t\t\t` - export const YourPlugin = createPlugin({...})\\n` +\n\t\t\t\t\t\t\t\t\t` - export default createPlugin({...})\\n` +\n\t\t\t\t\t\t\t\t\t`${containerInfo}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Validate it looks like a plugin constructor (has binding property)\n\t\t\t\t\t\t\tif (!(Constructor as any).binding) {\n\t\t\t\t\t\t\t\tconst containerInfo = typeof container === \"object\"\n\t\t\t\t\t\t\t\t\t? `Found exports: ${Object.keys(container).join(', ')}`\n\t\t\t\t\t\t\t\t\t: `Container type: ${typeof container}`;\n\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t`Invalid plugin constructor for '${pluginId}'. ` +\n\t\t\t\t\t\t\t\t\t`The exported value must be created with createPlugin(). ` +\n\t\t\t\t\t\t\t\t\t`Found a function but it's missing the required 'binding' property.\\n` +\n\t\t\t\t\t\t\t\t\t`${containerInfo}`,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconsole.log(`[MF] ✅ Loaded constructor for ${pluginId}`);\n\t\t\t\t\t\t\treturn Constructor;\n\t\t\t\t\t\t},\n\t\t\t\t\t\tcatch: (error): ModuleFederationError =>\n\t\t\t\t\t\t\tnew ModuleFederationError({\n\t\t\t\t\t\t\t\tpluginId,\n\t\t\t\t\t\t\t\tremoteUrl: url,\n\t\t\t\t\t\t\t\tcause:\n\t\t\t\t\t\t\t\t\terror instanceof Error ? error : new Error(String(error)),\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t});\n\t\t\t\t}),\n\t\t};\n\t}),\n}) {}\n"],"mappings":"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"}
|
|
@@ -1,3 +1,23 @@
|
|
|
1
|
-
const require_normalize = require('../../normalize-D4Qh0wVk.cjs');
|
|
2
1
|
|
|
3
|
-
|
|
2
|
+
//#region src/runtime/services/normalize.ts
|
|
3
|
+
/**
|
|
4
|
+
* Normalizes a package name into the module federation remote name.
|
|
5
|
+
* This function must produce identical results in both runtime and build contexts.
|
|
6
|
+
*
|
|
7
|
+
* Normalization rules:
|
|
8
|
+
* - Convert to lowercase
|
|
9
|
+
* - Strip a single leading '@' symbol
|
|
10
|
+
* - Replace '/' with '_'
|
|
11
|
+
* - Preserve hyphens and other characters
|
|
12
|
+
*
|
|
13
|
+
* Examples:
|
|
14
|
+
* - "@scope/my-plugin" → "scope_my-plugin"
|
|
15
|
+
* - "@SCOPE/Foo/Bar" → "scope_foo_bar"
|
|
16
|
+
* - "foo/bar" → "foo_bar"
|
|
17
|
+
* - "simple-plugin" → "simple-plugin"
|
|
18
|
+
*/
|
|
19
|
+
const getNormalizedRemoteName = (name) => name.toLowerCase().replace(/^@/, "").replace(/\//g, "_");
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
exports.getNormalizedRemoteName = getNormalizedRemoteName;
|
|
23
|
+
//# sourceMappingURL=normalize.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.cjs","names":[],"sources":["../../../src/runtime/services/normalize.ts"],"sourcesContent":["/**\n * Normalizes a package name into the module federation remote name.\n * This function must produce identical results in both runtime and build contexts.\n * \n * Normalization rules:\n * - Convert to lowercase\n * - Strip a single leading '@' symbol\n * - Replace '/' with '_'\n * - Preserve hyphens and other characters\n * \n * Examples:\n * - \"@scope/my-plugin\" → \"scope_my-plugin\"\n * - \"@SCOPE/Foo/Bar\" → \"scope_foo_bar\"\n * - \"foo/bar\" → \"foo_bar\"\n * - \"simple-plugin\" → \"simple-plugin\"\n */\nexport const getNormalizedRemoteName = (name: string): string =>\n name.toLowerCase().replace(/^@/, \"\").replace(/\\//g, \"_\");\n"],"mappings":";;;;;;;;;;;;;;;;;;AAgBA,MAAa,2BAA2B,SACtC,KAAK,aAAa,CAAC,QAAQ,MAAM,GAAG,CAAC,QAAQ,OAAO,IAAI"}
|
|
@@ -1,2 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/runtime/services/normalize.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a package name into the module federation remote name.
|
|
4
|
+
* This function must produce identical results in both runtime and build contexts.
|
|
5
|
+
*
|
|
6
|
+
* Normalization rules:
|
|
7
|
+
* - Convert to lowercase
|
|
8
|
+
* - Strip a single leading '@' symbol
|
|
9
|
+
* - Replace '/' with '_'
|
|
10
|
+
* - Preserve hyphens and other characters
|
|
11
|
+
*
|
|
12
|
+
* Examples:
|
|
13
|
+
* - "@scope/my-plugin" → "scope_my-plugin"
|
|
14
|
+
* - "@SCOPE/Foo/Bar" → "scope_foo_bar"
|
|
15
|
+
* - "foo/bar" → "foo_bar"
|
|
16
|
+
* - "simple-plugin" → "simple-plugin"
|
|
17
|
+
*/
|
|
18
|
+
declare const getNormalizedRemoteName: (name: string) => string;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { getNormalizedRemoteName };
|
|
21
|
+
//# sourceMappingURL=normalize.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.cts","names":[],"sources":["../../../src/runtime/services/normalize.ts"],"sourcesContent":[],"mappings":";;AAgBA;;;;;;;;;;;;;;;cAAa"}
|
|
@@ -1,2 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
//#region src/runtime/services/normalize.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a package name into the module federation remote name.
|
|
4
|
+
* This function must produce identical results in both runtime and build contexts.
|
|
5
|
+
*
|
|
6
|
+
* Normalization rules:
|
|
7
|
+
* - Convert to lowercase
|
|
8
|
+
* - Strip a single leading '@' symbol
|
|
9
|
+
* - Replace '/' with '_'
|
|
10
|
+
* - Preserve hyphens and other characters
|
|
11
|
+
*
|
|
12
|
+
* Examples:
|
|
13
|
+
* - "@scope/my-plugin" → "scope_my-plugin"
|
|
14
|
+
* - "@SCOPE/Foo/Bar" → "scope_foo_bar"
|
|
15
|
+
* - "foo/bar" → "foo_bar"
|
|
16
|
+
* - "simple-plugin" → "simple-plugin"
|
|
17
|
+
*/
|
|
18
|
+
declare const getNormalizedRemoteName: (name: string) => string;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { getNormalizedRemoteName };
|
|
21
|
+
//# sourceMappingURL=normalize.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.d.mts","names":[],"sources":["../../../src/runtime/services/normalize.ts"],"sourcesContent":[],"mappings":";;AAgBA;;;;;;;;;;;;;;;cAAa"}
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/runtime/services/normalize.ts
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes a package name into the module federation remote name.
|
|
4
|
+
* This function must produce identical results in both runtime and build contexts.
|
|
5
|
+
*
|
|
6
|
+
* Normalization rules:
|
|
7
|
+
* - Convert to lowercase
|
|
8
|
+
* - Strip a single leading '@' symbol
|
|
9
|
+
* - Replace '/' with '_'
|
|
10
|
+
* - Preserve hyphens and other characters
|
|
11
|
+
*
|
|
12
|
+
* Examples:
|
|
13
|
+
* - "@scope/my-plugin" → "scope_my-plugin"
|
|
14
|
+
* - "@SCOPE/Foo/Bar" → "scope_foo_bar"
|
|
15
|
+
* - "foo/bar" → "foo_bar"
|
|
16
|
+
* - "simple-plugin" → "simple-plugin"
|
|
17
|
+
*/
|
|
18
|
+
const getNormalizedRemoteName = (name) => name.toLowerCase().replace(/^@/, "").replace(/\//g, "_");
|
|
2
19
|
|
|
3
|
-
|
|
20
|
+
//#endregion
|
|
21
|
+
export { getNormalizedRemoteName };
|
|
22
|
+
//# sourceMappingURL=normalize.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize.mjs","names":[],"sources":["../../../src/runtime/services/normalize.ts"],"sourcesContent":["/**\n * Normalizes a package name into the module federation remote name.\n * This function must produce identical results in both runtime and build contexts.\n * \n * Normalization rules:\n * - Convert to lowercase\n * - Strip a single leading '@' symbol\n * - Replace '/' with '_'\n * - Preserve hyphens and other characters\n * \n * Examples:\n * - \"@scope/my-plugin\" → \"scope_my-plugin\"\n * - \"@SCOPE/Foo/Bar\" → \"scope_foo_bar\"\n * - \"foo/bar\" → \"foo_bar\"\n * - \"simple-plugin\" → \"simple-plugin\"\n */\nexport const getNormalizedRemoteName = (name: string): string =>\n name.toLowerCase().replace(/^@/, \"\").replace(/\\//g, \"_\");\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,MAAa,2BAA2B,SACtC,KAAK,aAAa,CAAC,QAAQ,MAAM,GAAG,CAAC,QAAQ,OAAO,IAAI"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_errors = require('../errors.cjs');
|
|
3
|
+
let effect = require("effect");
|
|
4
|
+
|
|
5
|
+
//#region src/runtime/services/plugin-lifecycle.service.ts
|
|
6
|
+
var PluginLifecycleService = class extends effect.Effect.Service()("PluginLifecycleService", { effect: effect.Effect.gen(function* () {
|
|
7
|
+
const activePlugins = yield* effect.Ref.make(/* @__PURE__ */ new Set());
|
|
8
|
+
return {
|
|
9
|
+
register: (plugin) => effect.Ref.update(activePlugins, (plugins) => new Set(plugins).add(plugin)),
|
|
10
|
+
unregister: (plugin) => effect.Ref.update(activePlugins, (plugins) => {
|
|
11
|
+
const newSet = new Set(plugins);
|
|
12
|
+
newSet.delete(plugin);
|
|
13
|
+
return newSet;
|
|
14
|
+
}),
|
|
15
|
+
shutdown: (plugin) => effect.Effect.gen(function* () {
|
|
16
|
+
yield* effect.Ref.update(activePlugins, (plugins) => {
|
|
17
|
+
const newSet = new Set(plugins);
|
|
18
|
+
newSet.delete(plugin);
|
|
19
|
+
return newSet;
|
|
20
|
+
});
|
|
21
|
+
yield* plugin.plugin.shutdown().pipe(effect.Effect.mapError((error) => require_errors.toPluginRuntimeError(error, plugin.plugin.id, void 0, "shutdown-plugin", false)));
|
|
22
|
+
}),
|
|
23
|
+
cleanup: () => effect.Effect.gen(function* () {
|
|
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" });
|
|
26
|
+
yield* effect.Ref.set(activePlugins, /* @__PURE__ */ new Set());
|
|
27
|
+
}).pipe(effect.Effect.catchAll(() => effect.Effect.void))
|
|
28
|
+
};
|
|
29
|
+
}) }) {};
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
exports.PluginLifecycleService = PluginLifecycleService;
|
|
33
|
+
//# sourceMappingURL=plugin-lifecycle.service.cjs.map
|
|
@@ -0,0 +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>()(\"PluginLifecycleService\", {\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.shutdown().pipe(\n Effect.mapError(error =>\n toPluginRuntimeError(error, plugin.plugin.id, undefined, \"shutdown-plugin\", false)\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(error, plugin.plugin.id, undefined, \"cleanup-shutdown\", false)\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"],"mappings":";;;;;AAIA,IAAa,yBAAb,cAA4CA,cAAO,SAAiC,CAAC,0BAA0B,EAC7G,QAAQA,cAAO,IAAI,aAAa;CAC9B,MAAM,gBAAgB,OAAOC,WAAI,qBAAK,IAAI,KAAmC,CAAC;AAE9E,QAAO;EACL,WAAgC,WAC9BA,WAAI,OAAO,gBAAe,YACxB,IAAI,IAAI,QAAQ,CAAC,IAAI,OAAuC,CAC7D;EAEH,aAAa,WACXA,WAAI,OAAO,gBAAe,YAAW;GACnC,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,UAAO,OAAO,OAAO;AACrB,UAAO;IACP;EAEJ,WAAW,WACTD,cAAO,IAAI,aAAa;AAEtB,UAAOC,WAAI,OAAO,gBAAe,YAAW;IAC1C,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,WAAO,OAAO,OAAO;AACrB,WAAO;KACP;AAGF,UAAO,OAAO,OAAO,UAAU,CAAC,KAC9BD,cAAO,UAAS,UACdE,oCAAqB,OAAO,OAAO,OAAO,IAAI,QAAW,mBAAmB,MAAM,CACnF,CACF;IACD;EAEJ,eACEF,cAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAOC,WAAI,IAAI,cAAc;AAG7C,UAAOD,cAAO,QACZ,UACA,WACE,OAAO,OAAO,UAAU,CAAC,KACvBA,cAAO,UAAS,UACdE,oCAAqB,OAAO,OAAO,OAAO,IAAI,QAAW,oBAAoB,MAAM,CACpF,EACDF,cAAO,UAAS,UACdA,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,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AnyPlugin, InitializedPlugin } from "../../types.cjs";
|
|
2
|
+
import { PluginRuntimeError } from "../errors.cjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/runtime/services/plugin-lifecycle.service.d.ts
|
|
6
|
+
declare const PluginLifecycleService_base: Effect.Service.Class<PluginLifecycleService, "PluginLifecycleService", {
|
|
7
|
+
readonly effect: Effect.Effect<{
|
|
8
|
+
register: <T extends AnyPlugin>(plugin: InitializedPlugin<T>) => Effect.Effect<void, never, never>;
|
|
9
|
+
unregister: (plugin: InitializedPlugin<AnyPlugin>) => Effect.Effect<void, never, never>;
|
|
10
|
+
shutdown: (plugin: InitializedPlugin<AnyPlugin>) => Effect.Effect<void, PluginRuntimeError, never>;
|
|
11
|
+
cleanup: () => Effect.Effect<void, never, never>;
|
|
12
|
+
}, never, never>;
|
|
13
|
+
}>;
|
|
14
|
+
declare class PluginLifecycleService extends PluginLifecycleService_base {}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { PluginLifecycleService };
|
|
17
|
+
//# sourceMappingURL=plugin-lifecycle.service.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-lifecycle.service.d.cts","names":[],"sources":["../../../src/runtime/services/plugin-lifecycle.service.ts"],"sourcesContent":[],"mappings":";;;;;cACgE;;yBAQrC,mBAAmB,kBAAkB,OAAE,MAAA,CAAA;IARF,UAAA,EAAA,CAAA,MAAA,EAarC,iBAbqC,CAanB,SAbmB,CAAA,EAAA,GAaT,MAAA,CAAA,MAbS,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;uBAoBvC,kBAAkB,eAAU,MAAA,CAAA,aAAX,kBAAA;IAZf,OAAA,EAAA,GAAA,gBAAA,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;EAAqC,CAAA,EAAA,KAAA,EAAA,KAAA,CAAA;CAAlB,CAAA;AAAoB,cALrD,sBAAA,SAA+B,2BAAA,CAKsB"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { AnyPlugin, InitializedPlugin } from "../../types.mjs";
|
|
2
|
+
import { PluginRuntimeError } from "../errors.mjs";
|
|
3
|
+
import { Effect } from "effect";
|
|
4
|
+
|
|
5
|
+
//#region src/runtime/services/plugin-lifecycle.service.d.ts
|
|
6
|
+
declare const PluginLifecycleService_base: Effect.Service.Class<PluginLifecycleService, "PluginLifecycleService", {
|
|
7
|
+
readonly effect: Effect.Effect<{
|
|
8
|
+
register: <T extends AnyPlugin>(plugin: InitializedPlugin<T>) => Effect.Effect<void, never, never>;
|
|
9
|
+
unregister: (plugin: InitializedPlugin<AnyPlugin>) => Effect.Effect<void, never, never>;
|
|
10
|
+
shutdown: (plugin: InitializedPlugin<AnyPlugin>) => Effect.Effect<void, PluginRuntimeError, never>;
|
|
11
|
+
cleanup: () => Effect.Effect<void, never, never>;
|
|
12
|
+
}, never, never>;
|
|
13
|
+
}>;
|
|
14
|
+
declare class PluginLifecycleService extends PluginLifecycleService_base {}
|
|
15
|
+
//#endregion
|
|
16
|
+
export { PluginLifecycleService };
|
|
17
|
+
//# sourceMappingURL=plugin-lifecycle.service.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-lifecycle.service.d.mts","names":[],"sources":["../../../src/runtime/services/plugin-lifecycle.service.ts"],"sourcesContent":[],"mappings":";;;;;cACgE;;yBAQrC,mBAAmB,kBAAkB,OAAE,MAAA,CAAA;IARF,UAAA,EAAA,CAAA,MAAA,EAarC,iBAbqC,CAanB,SAbmB,CAAA,EAAA,GAaT,MAAA,CAAA,MAbS,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;uBAoBvC,kBAAkB,eAAU,MAAA,CAAA,aAAX,kBAAA;IAZf,OAAA,EAAA,GAAA,gBAAA,CAAA,IAAA,EAAA,KAAA,EAAA,KAAA,CAAA;EAAqC,CAAA,EAAA,KAAA,EAAA,KAAA,CAAA;CAAlB,CAAA;AAAoB,cALrD,sBAAA,SAA+B,2BAAA,CAKsB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { toPluginRuntimeError } from "../errors.mjs";
|
|
2
|
+
import { Effect, Ref } from "effect";
|
|
3
|
+
|
|
4
|
+
//#region src/runtime/services/plugin-lifecycle.service.ts
|
|
5
|
+
var PluginLifecycleService = class extends Effect.Service()("PluginLifecycleService", { effect: Effect.gen(function* () {
|
|
6
|
+
const activePlugins = yield* Ref.make(/* @__PURE__ */ new Set());
|
|
7
|
+
return {
|
|
8
|
+
register: (plugin) => Ref.update(activePlugins, (plugins) => new Set(plugins).add(plugin)),
|
|
9
|
+
unregister: (plugin) => Ref.update(activePlugins, (plugins) => {
|
|
10
|
+
const newSet = new Set(plugins);
|
|
11
|
+
newSet.delete(plugin);
|
|
12
|
+
return newSet;
|
|
13
|
+
}),
|
|
14
|
+
shutdown: (plugin) => Effect.gen(function* () {
|
|
15
|
+
yield* Ref.update(activePlugins, (plugins) => {
|
|
16
|
+
const newSet = new Set(plugins);
|
|
17
|
+
newSet.delete(plugin);
|
|
18
|
+
return newSet;
|
|
19
|
+
});
|
|
20
|
+
yield* plugin.plugin.shutdown().pipe(Effect.mapError((error) => toPluginRuntimeError(error, plugin.plugin.id, void 0, "shutdown-plugin", false)));
|
|
21
|
+
}),
|
|
22
|
+
cleanup: () => Effect.gen(function* () {
|
|
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" });
|
|
25
|
+
yield* Ref.set(activePlugins, /* @__PURE__ */ new Set());
|
|
26
|
+
}).pipe(Effect.catchAll(() => Effect.void))
|
|
27
|
+
};
|
|
28
|
+
}) }) {};
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { PluginLifecycleService };
|
|
32
|
+
//# sourceMappingURL=plugin-lifecycle.service.mjs.map
|
|
@@ -0,0 +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>()(\"PluginLifecycleService\", {\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.shutdown().pipe(\n Effect.mapError(error =>\n toPluginRuntimeError(error, plugin.plugin.id, undefined, \"shutdown-plugin\", false)\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(error, plugin.plugin.id, undefined, \"cleanup-shutdown\", false)\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"],"mappings":";;;;AAIA,IAAa,yBAAb,cAA4C,OAAO,SAAiC,CAAC,0BAA0B,EAC7G,QAAQ,OAAO,IAAI,aAAa;CAC9B,MAAM,gBAAgB,OAAO,IAAI,qBAAK,IAAI,KAAmC,CAAC;AAE9E,QAAO;EACL,WAAgC,WAC9B,IAAI,OAAO,gBAAe,YACxB,IAAI,IAAI,QAAQ,CAAC,IAAI,OAAuC,CAC7D;EAEH,aAAa,WACX,IAAI,OAAO,gBAAe,YAAW;GACnC,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,UAAO,OAAO,OAAO;AACrB,UAAO;IACP;EAEJ,WAAW,WACT,OAAO,IAAI,aAAa;AAEtB,UAAO,IAAI,OAAO,gBAAe,YAAW;IAC1C,MAAM,SAAS,IAAI,IAAI,QAAQ;AAC/B,WAAO,OAAO,OAAO;AACrB,WAAO;KACP;AAGF,UAAO,OAAO,OAAO,UAAU,CAAC,KAC9B,OAAO,UAAS,UACd,qBAAqB,OAAO,OAAO,OAAO,IAAI,QAAW,mBAAmB,MAAM,CACnF,CACF;IACD;EAEJ,eACE,OAAO,IAAI,aAAa;GACtB,MAAM,UAAU,OAAO,IAAI,IAAI,cAAc;AAG7C,UAAO,OAAO,QACZ,UACA,WACE,OAAO,OAAO,UAAU,CAAC,KACvB,OAAO,UAAS,UACd,qBAAqB,OAAO,OAAO,OAAO,IAAI,QAAW,oBAAoB,MAAM,CACpF,EACD,OAAO,UAAS,UACd,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,CAAC,CAAC"}
|