@squide/firefly-module-federation 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ export { initializeFirefly, type InitializeFireflyOptions } from "./initializeFirefly.ts";
2
+ export { getModuleFederationPlugin, ModuleFederationPluginName, type ModuleFederationPlugin } from "./ModuleFederationPlugin.ts";
3
+ export type { RemoteDefinition } from "./RemoteDefinition.ts";
4
+ export { RemoteModuleDeferredRegistrationFailedEvent, RemoteModuleDeferredRegistrationUpdateFailedEvent, RemoteModuleRegistrationFailedEvent, RemoteModuleRegistryId, RemoteModulesDeferredRegistrationCompletedEvent, RemoteModulesDeferredRegistrationStartedEvent, RemoteModulesDeferredRegistrationsUpdateCompletedEvent, RemoteModulesDeferredRegistrationsUpdateStartedEvent, RemoteModulesRegistrationCompletedEvent, RemoteModulesRegistrationStartedEvent, type RemoteModuleRegistrationError, type RemoteModulesDeferredRegistrationCompletedEventPayload, type RemoteModulesDeferredRegistrationStartedEventPayload, type RemoteModulesDeferredRegistrationsUpdateCompletedEventPayload, type RemoteModulesDeferredRegistrationsUpdateStartedEventPayload, type RemoteModulesRegistrationCompletedEventPayload, type RemoteModulesRegistrationStartedEventPayload } from "./RemoteModuleRegistry.ts";
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ import { initializeFirefly } from "./initializeFirefly.js";
2
+ import { ModuleFederationPluginName, getModuleFederationPlugin } from "./ModuleFederationPlugin.js";
3
+ import { RemoteModuleDeferredRegistrationFailedEvent, RemoteModuleDeferredRegistrationUpdateFailedEvent, RemoteModuleRegistrationFailedEvent, RemoteModuleRegistryId, RemoteModulesDeferredRegistrationCompletedEvent, RemoteModulesDeferredRegistrationStartedEvent, RemoteModulesDeferredRegistrationsUpdateCompletedEvent, RemoteModulesDeferredRegistrationsUpdateStartedEvent, RemoteModulesRegistrationCompletedEvent, RemoteModulesRegistrationStartedEvent } from "./RemoteModuleRegistry.js";
4
+
5
+ ;// CONCATENATED MODULE: external "./initializeFirefly.js"
6
+
7
+ ;// CONCATENATED MODULE: external "./ModuleFederationPlugin.js"
8
+
9
+ ;// CONCATENATED MODULE: external "./RemoteModuleRegistry.js"
10
+
11
+ ;// CONCATENATED MODULE: ./src/index.ts
12
+
13
+
14
+
15
+
16
+ export { ModuleFederationPluginName, RemoteModuleDeferredRegistrationFailedEvent, RemoteModuleDeferredRegistrationUpdateFailedEvent, RemoteModuleRegistrationFailedEvent, RemoteModuleRegistryId, RemoteModulesDeferredRegistrationCompletedEvent, RemoteModulesDeferredRegistrationStartedEvent, RemoteModulesDeferredRegistrationsUpdateCompletedEvent, RemoteModulesDeferredRegistrationsUpdateStartedEvent, RemoteModulesRegistrationCompletedEvent, RemoteModulesRegistrationStartedEvent, getModuleFederationPlugin, initializeFirefly };
17
+
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["export { initializeFirefly, type InitializeFireflyOptions } from \"./initializeFirefly.ts\";\nexport { getModuleFederationPlugin, ModuleFederationPluginName, type ModuleFederationPlugin } from \"./ModuleFederationPlugin.ts\";\nexport type { RemoteDefinition } from \"./RemoteDefinition.ts\";\nexport {\n RemoteModuleDeferredRegistrationFailedEvent,\n RemoteModuleDeferredRegistrationUpdateFailedEvent,\n RemoteModuleRegistrationFailedEvent,\n RemoteModuleRegistryId,\n RemoteModulesDeferredRegistrationCompletedEvent,\n RemoteModulesDeferredRegistrationStartedEvent,\n RemoteModulesDeferredRegistrationsUpdateCompletedEvent,\n RemoteModulesDeferredRegistrationsUpdateStartedEvent,\n RemoteModulesRegistrationCompletedEvent,\n RemoteModulesRegistrationStartedEvent,\n type RemoteModuleRegistrationError,\n type RemoteModulesDeferredRegistrationCompletedEventPayload,\n type RemoteModulesDeferredRegistrationStartedEventPayload,\n type RemoteModulesDeferredRegistrationsUpdateCompletedEventPayload,\n type RemoteModulesDeferredRegistrationsUpdateStartedEventPayload,\n type RemoteModulesRegistrationCompletedEventPayload,\n type RemoteModulesRegistrationStartedEventPayload\n} from \"./RemoteModuleRegistry.ts\";\n\n"],"names":["initializeFirefly","getModuleFederationPlugin","ModuleFederationPluginName","RemoteModuleDeferredRegistrationFailedEvent","RemoteModuleDeferredRegistrationUpdateFailedEvent","RemoteModuleRegistrationFailedEvent","RemoteModuleRegistryId","RemoteModulesDeferredRegistrationCompletedEvent","RemoteModulesDeferredRegistrationStartedEvent","RemoteModulesDeferredRegistrationsUpdateCompletedEvent","RemoteModulesDeferredRegistrationsUpdateStartedEvent","RemoteModulesRegistrationCompletedEvent","RemoteModulesRegistrationStartedEvent"],"mappings":";;;;;;;;;;;AAA0F;AACuC;AAoB9F"}
@@ -0,0 +1,6 @@
1
+ import { FireflyRuntime, type InitializeFireflyOptions as BaseInitializeFireflyOptions } from "@squide/firefly";
2
+ import { RemoteDefinition } from "./RemoteDefinition.ts";
3
+ export interface InitializeFireflyOptions<TRuntime extends FireflyRuntime, TContext = unknown, TData = unknown> extends BaseInitializeFireflyOptions<TRuntime, TContext, TData> {
4
+ remotes?: RemoteDefinition[];
5
+ }
6
+ export declare function initializeFirefly<TContext = unknown, TData = unknown>(options?: InitializeFireflyOptions<FireflyRuntime, TContext, TData>): FireflyRuntime<any>;
@@ -0,0 +1,32 @@
1
+ import { initializeFirefly } from "@squide/firefly";
2
+ import { ModuleFederationPlugin } from "./ModuleFederationPlugin.js";
3
+ import { toRemoteModuleDefinitions } from "./RemoteModuleRegistry.js";
4
+
5
+ ;// CONCATENATED MODULE: external "@squide/firefly"
6
+
7
+ ;// CONCATENATED MODULE: external "./ModuleFederationPlugin.js"
8
+
9
+ ;// CONCATENATED MODULE: external "./RemoteModuleRegistry.js"
10
+
11
+ ;// CONCATENATED MODULE: ./src/initializeFirefly.ts
12
+
13
+
14
+
15
+ function initializeFirefly_initializeFirefly(options = {}) {
16
+ const { remotes = [], moduleDefinitions = [], plugins = [], ...rest } = options;
17
+ return initializeFirefly({
18
+ moduleDefinitions: [
19
+ ...moduleDefinitions,
20
+ ...toRemoteModuleDefinitions(remotes)
21
+ ],
22
+ plugins: [
23
+ (x)=>new ModuleFederationPlugin(x),
24
+ ...plugins
25
+ ],
26
+ ...rest
27
+ });
28
+ }
29
+
30
+ export { initializeFirefly_initializeFirefly as initializeFirefly };
31
+
32
+ //# sourceMappingURL=initializeFirefly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"initializeFirefly.js","sources":["../src/initializeFirefly.ts"],"sourcesContent":["import { FireflyRuntime, initializeFirefly as baseInitializeFirefly, type InitializeFireflyOptions as BaseInitializeFireflyOptions } from \"@squide/firefly\";\nimport { ModuleFederationPlugin } from \"./ModuleFederationPlugin.ts\";\nimport { RemoteDefinition } from \"./RemoteDefinition.ts\";\nimport { toRemoteModuleDefinitions } from \"./RemoteModuleRegistry.ts\";\n\nexport interface InitializeFireflyOptions<TRuntime extends FireflyRuntime, TContext = unknown, TData = unknown> extends BaseInitializeFireflyOptions<TRuntime, TContext, TData> {\n remotes?: RemoteDefinition[];\n}\n\nexport function initializeFirefly<TContext = unknown, TData = unknown>(options: InitializeFireflyOptions<FireflyRuntime, TContext, TData> = {}) {\n const {\n remotes = [],\n moduleDefinitions = [],\n plugins = [],\n ...rest\n } = options;\n\n return baseInitializeFirefly({\n moduleDefinitions: [\n ...moduleDefinitions,\n ...toRemoteModuleDefinitions(remotes)\n ],\n plugins: [\n x => new ModuleFederationPlugin(x),\n ...plugins\n ],\n ...rest\n });\n}\n"],"names":["initializeFirefly","baseInitializeFirefly","ModuleFederationPlugin","toRemoteModuleDefinitions","options","remotes","moduleDefinitions","plugins","rest","x"],"mappings":";;;;;;;;;;;AAA4J;AACvF;AAEC;AAM/D,SAASA,mCAAiBA,CAAsCI,UAAqE,CAAC,CAAC;IAC1I,MAAM,EACFC,UAAU,EAAE,EACZC,oBAAoB,EAAE,EACtBC,UAAU,EAAE,EACZ,GAAGC,MACN,GAAGJ;IAEJ,OAAOH,iBAAqBA,CAAC;QACzB,mBAAmB;eACZK;eACAH,yBAAyBA,CAACE;SAChC;QACD,SAAS;YACLI,CAAAA,IAAK,IAAIP,sBAAsBA,CAACO;eAC7BF;SACN;QACD,GAAGC,IAAI;IACX;AACJ"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@squide/firefly-module-federation",
3
+ "author": "Workleap",
4
+ "version": "0.0.0",
5
+ "description": "Add support for Module Federation to @squide application shell.",
6
+ "license": "Apache-2.0",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/workleap/wl-squide.git",
10
+ "directory": "packages/firefly-module-federation"
11
+ },
12
+ "type": "module",
13
+ "publishConfig": {
14
+ "access": "public",
15
+ "provenance": true,
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.js",
20
+ "default": "./dist/index.js"
21
+ }
22
+ }
23
+ },
24
+ "exports": "./src/index.ts",
25
+ "files": [
26
+ "src",
27
+ "dist",
28
+ "CHANGELOG.md"
29
+ ],
30
+ "scripts": {
31
+ "build": "rslib build --config ./rslib.build.ts",
32
+ "eslint": "eslint . --max-warnings=0 --cache --cache-location node_modules/.cache/eslint",
33
+ "typecheck": "tsc",
34
+ "test": "vitest --config vitest.config.ts --no-watch"
35
+ },
36
+ "peerDependencies": {
37
+ "@opentelemetry/api": "^1.9.0",
38
+ "@tanstack/react-query": "^5.90.10",
39
+ "msw": "^2.12.2",
40
+ "react": "^18.0.0 || ^19.0.0",
41
+ "react-dom": "^18.0.0 || ^19.0.0",
42
+ "react-router": "^7.9.6"
43
+ },
44
+ "dependencies": {
45
+ "@module-federation/enhanced": "0.11.4",
46
+ "@rspack/core": "^1.6.4",
47
+ "@squide/core": "workspace:*",
48
+ "@squide/firefly": "workspace:*",
49
+ "@workleap/logging": "^1.3.2"
50
+ },
51
+ "devDependencies": {
52
+ "@eslint/js": "9.39.1",
53
+ "@rsbuild/core": "1.6.7",
54
+ "@rslib/core": "0.18.0",
55
+ "@testing-library/react": "16.3.0",
56
+ "@types/react": "19.2.6",
57
+ "@types/react-dom": "19.2.3",
58
+ "@typescript-eslint/parser": "8.47.0",
59
+ "@vitejs/plugin-react": "5.1.1",
60
+ "@workleap/eslint-configs": "1.1.5",
61
+ "@workleap/rslib-configs": "1.1.3",
62
+ "@workleap/typescript-configs": "3.0.7",
63
+ "eslint": "9.39.1",
64
+ "happy-dom": "20.0.10",
65
+ "typescript": "5.9.3",
66
+ "typescript-eslint": "8.47.0",
67
+ "vitest": "4.0.10"
68
+ },
69
+ "sideEffects": false
70
+ }
@@ -0,0 +1,216 @@
1
+ import { loadRemote as loadModuleFederationRemote } from "@module-federation/enhanced/runtime";
2
+ import { Span } from "@opentelemetry/api";
3
+ import { isNil, Plugin, RegisterModulesOptions, type Runtime } from "@squide/core";
4
+ import { FireflyPlugin, FireflyRuntime } from "@squide/firefly";
5
+ import { ActiveSpan, addProtectedListener, endActiveSpan, getTracer, HoneycombTrackingUnmanagedErrorHandler, startActiveChildSpan, startChildSpan, traceError, type GetSpanFunction } from "@squide/firefly/internal";
6
+ import { RemoteDefinition } from "./RemoteDefinition.ts";
7
+ import { RemoteModuleDeferredRegistrationFailedEvent, RemoteModuleDeferredRegistrationUpdateFailedEvent, RemoteModuleRegistrationError, RemoteModuleRegistrationFailedEvent, RemoteModuleRegistry, RemoteModuleRegistryId, RemoteModulesDeferredRegistrationCompletedEvent, RemoteModulesDeferredRegistrationCompletedEventPayload, RemoteModulesDeferredRegistrationStartedEvent, RemoteModulesDeferredRegistrationStartedEventPayload, RemoteModulesDeferredRegistrationsUpdateCompletedEvent, RemoteModulesDeferredRegistrationsUpdateCompletedEventPayload, RemoteModulesDeferredRegistrationsUpdateStartedEvent, RemoteModulesDeferredRegistrationsUpdateStartedEventPayload, RemoteModulesRegistrationCompletedEvent, RemoteModulesRegistrationCompletedEventPayload, RemoteModulesRegistrationStartedEvent, RemoteModulesRegistrationStartedEventPayload } from "./RemoteModuleRegistry.ts";
8
+
9
+ export const ModuleFederationPluginName = "module-federation-plugin";
10
+
11
+ export class ModuleFederationPlugin extends Plugin<FireflyRuntime> implements FireflyPlugin {
12
+ constructor(runtime: FireflyRuntime) {
13
+ super(ModuleFederationPluginName, runtime);
14
+
15
+ this._runtime.moduleManager.addModuleRegistry(new RemoteModuleRegistry((remoteName, moduleName) => loadModuleFederationRemote(`${remoteName}/${moduleName}`)));
16
+ }
17
+
18
+ registerRemoteModules<TContext = unknown>(remotes: RemoteDefinition[], options?: RegisterModulesOptions<TContext>) {
19
+ return this._runtime.moduleManager.registerModules(remotes.map(x => ({
20
+ definition: x,
21
+ registryId: RemoteModuleRegistryId
22
+ })), options);
23
+ }
24
+
25
+ registerHoneycombTrackingListeners(
26
+ getBootstrappingSpan: GetSpanFunction,
27
+ getDeferredRegistrationsUpdateSpan: GetSpanFunction,
28
+ onUnmanagedError: HoneycombTrackingUnmanagedErrorHandler
29
+ ) {
30
+ let remoteModuleRegistrationSpan: Span;
31
+ let remoteModuleDeferredRegistrationSpan: Span;
32
+ let remoteModuleDeferredRegistrationsUpdateSpan: ActiveSpan;
33
+
34
+ const handleUnmanagedError = (error: unknown) => {
35
+ if (remoteModuleRegistrationSpan) {
36
+ remoteModuleRegistrationSpan.end();
37
+ }
38
+
39
+ if (remoteModuleDeferredRegistrationSpan) {
40
+ remoteModuleDeferredRegistrationSpan.end();
41
+ }
42
+
43
+ if (remoteModuleDeferredRegistrationsUpdateSpan) {
44
+ remoteModuleDeferredRegistrationsUpdateSpan.instance.end();
45
+ }
46
+
47
+ onUnmanagedError(error);
48
+ };
49
+
50
+ addProtectedListener(this._runtime, RemoteModulesRegistrationStartedEvent, (payload: unknown) => {
51
+ const bootstrappingSpan = getBootstrappingSpan();
52
+
53
+ const attributes = {
54
+ "app.squide.remote_count": (payload as RemoteModulesRegistrationStartedEventPayload).remoteCount
55
+ };
56
+
57
+ if (bootstrappingSpan) {
58
+ bootstrappingSpan.addEvent("remote-module-registration-started", attributes);
59
+ }
60
+
61
+ remoteModuleRegistrationSpan = startChildSpan(bootstrappingSpan, (options, context) => {
62
+ return getTracer().startSpan("remote-module-registration", { ...options, attributes }, context);
63
+ });
64
+ }, {
65
+ once: true,
66
+ onError: handleUnmanagedError
67
+ });
68
+
69
+ addProtectedListener(this._runtime, RemoteModulesRegistrationCompletedEvent, (payload: unknown) => {
70
+ const bootstrappingSpan = getBootstrappingSpan();
71
+
72
+ if (bootstrappingSpan) {
73
+ bootstrappingSpan.addEvent("remote-module-registration-completed", {
74
+ "app.squide.remote_count": (payload as RemoteModulesRegistrationCompletedEventPayload).remoteCount
75
+ });
76
+ }
77
+
78
+ if (remoteModuleRegistrationSpan) {
79
+ remoteModuleRegistrationSpan.end();
80
+ }
81
+ }, {
82
+ once: true,
83
+ onError: handleUnmanagedError
84
+ });
85
+
86
+ // Can occur multiple times.
87
+ addProtectedListener(this._runtime, RemoteModuleRegistrationFailedEvent, (payload: unknown) => {
88
+ const registrationError = payload as RemoteModuleRegistrationError;
89
+
90
+ if (remoteModuleRegistrationSpan) {
91
+ traceError(remoteModuleRegistrationSpan, registrationError);
92
+ }
93
+ }, {
94
+ onError: handleUnmanagedError
95
+ });
96
+
97
+ addProtectedListener(this._runtime, RemoteModulesDeferredRegistrationStartedEvent, (payload: unknown) => {
98
+ const bootstrappingSpan = getBootstrappingSpan();
99
+
100
+ const attributes = {
101
+ "app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationStartedEventPayload).registrationCount
102
+ };
103
+
104
+ if (bootstrappingSpan) {
105
+ bootstrappingSpan.addEvent("remote-module-deferred-registration-started", attributes);
106
+ }
107
+
108
+ remoteModuleDeferredRegistrationSpan = startChildSpan(bootstrappingSpan, (options, context) => {
109
+ return getTracer().startSpan("remote-module-deferred-registration", { ...options, attributes }, context);
110
+ });
111
+ }, {
112
+ once: true,
113
+ onError: handleUnmanagedError
114
+ });
115
+
116
+ addProtectedListener(this._runtime, RemoteModulesDeferredRegistrationCompletedEvent, (payload: unknown) => {
117
+ const bootstrappingSpan = getBootstrappingSpan();
118
+
119
+ if (bootstrappingSpan) {
120
+ bootstrappingSpan.addEvent("remote-module-deferred-registration-completed", {
121
+ "app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationCompletedEventPayload).registrationCount
122
+ });
123
+ }
124
+
125
+ if (remoteModuleDeferredRegistrationSpan) {
126
+ remoteModuleDeferredRegistrationSpan.end();
127
+ }
128
+ }, {
129
+ once: true,
130
+ onError: handleUnmanagedError
131
+ });
132
+
133
+ // Can occur multiple times.
134
+ addProtectedListener(this._runtime, RemoteModuleDeferredRegistrationFailedEvent, (payload: unknown) => {
135
+ const registrationError = payload as RemoteModuleRegistrationError;
136
+
137
+ if (remoteModuleDeferredRegistrationSpan) {
138
+ traceError(remoteModuleDeferredRegistrationSpan, registrationError);
139
+ }
140
+ }, {
141
+ onError: handleUnmanagedError
142
+ });
143
+
144
+ // Can occur multiple times.
145
+ addProtectedListener(this._runtime, RemoteModulesDeferredRegistrationsUpdateStartedEvent, (payload: unknown) => {
146
+ const deferredRegistrationsUpdateSpan = getDeferredRegistrationsUpdateSpan();
147
+
148
+ const attributes = {
149
+ "app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationsUpdateStartedEventPayload).registrationCount
150
+ };
151
+
152
+ if (deferredRegistrationsUpdateSpan) {
153
+ deferredRegistrationsUpdateSpan.addEvent("remote-module-deferred-registrations-update-started", attributes);
154
+ }
155
+
156
+ remoteModuleDeferredRegistrationsUpdateSpan = startActiveChildSpan(deferredRegistrationsUpdateSpan, (options, context) => {
157
+ const name = "remote-module-deferred-registrations-update";
158
+
159
+ const span = getTracer().startSpan(name, {
160
+ attributes,
161
+ ...options
162
+ }, context);
163
+
164
+ return {
165
+ name,
166
+ span
167
+ };
168
+ });
169
+ }, {
170
+ onError: handleUnmanagedError
171
+ });
172
+
173
+ // Can occur multiple times.
174
+ addProtectedListener(this._runtime, RemoteModulesDeferredRegistrationsUpdateCompletedEvent, (payload: unknown) => {
175
+ const deferredRegistrationsUpdateSpan = getDeferredRegistrationsUpdateSpan();
176
+
177
+ if (deferredRegistrationsUpdateSpan) {
178
+ deferredRegistrationsUpdateSpan.addEvent("remote-module-deferred-registrations-update-completed", {
179
+ "app.squide.registration_count": (payload as RemoteModulesDeferredRegistrationsUpdateCompletedEventPayload).registrationCount
180
+ });
181
+ }
182
+
183
+ if (remoteModuleDeferredRegistrationsUpdateSpan) {
184
+ endActiveSpan(remoteModuleDeferredRegistrationsUpdateSpan);
185
+ }
186
+ }, {
187
+ onError: handleUnmanagedError
188
+ });
189
+
190
+ // Can occur multiple times.
191
+ addProtectedListener(this._runtime, RemoteModuleDeferredRegistrationUpdateFailedEvent, (payload: unknown) => {
192
+ const registrationError = payload as RemoteModuleRegistrationError;
193
+
194
+ if (remoteModuleDeferredRegistrationsUpdateSpan) {
195
+ traceError(remoteModuleDeferredRegistrationsUpdateSpan.instance, registrationError);
196
+ }
197
+ }, {
198
+ onError: handleUnmanagedError
199
+ });
200
+
201
+ // Cleanup the spans if the root tracking is failing.
202
+ return (error: unknown) => {
203
+ handleUnmanagedError(error);
204
+ };
205
+ }
206
+ }
207
+
208
+ export function getModuleFederationPlugin(runtime: Runtime) {
209
+ const plugin = runtime.getPlugin(ModuleFederationPluginName);
210
+
211
+ if (isNil(plugin)) {
212
+ throw new Error("[squide] The getModuleFederationPlugin function is called but no ModuleFederationPlugin instance has been registered with the runtime.");
213
+ }
214
+
215
+ return plugin as ModuleFederationPlugin;
216
+ }
@@ -0,0 +1,5 @@
1
+ export interface RemoteDefinition extends Record<string, unknown> {
2
+ // The name of the remote module.
3
+ name: string;
4
+ }
5
+