@module-federation/observability-plugin 0.0.0-alpha.0 → 0.0.0-codex-node24-dev-node20-compat-ci-20260713063237

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2020 ScriptedAlchemy LLC (Zack Jackson) Zhou Shaw (zhouxiao)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -15,21 +15,19 @@ Node file output, and no raw error stack in console output.
15
15
  import { createInstance } from '@module-federation/runtime';
16
16
  import { ObservabilityPlugin } from '@module-federation/observability-plugin';
17
17
 
18
- const observability = ObservabilityPlugin({
19
- level: 'verbose',
20
- browser: {
21
- enabled: true,
22
- scope: 'host',
23
- },
24
- });
25
-
26
18
  createInstance({
27
19
  name: 'host',
28
- plugins: [observability.plugin],
20
+ plugins: [
21
+ ObservabilityPlugin({
22
+ level: 'verbose',
23
+ browser: {
24
+ enabled: true,
25
+ scope: 'host',
26
+ },
27
+ }),
28
+ ],
29
29
  remotes: [],
30
30
  });
31
-
32
- const report = observability.getLatestReport();
33
31
  ```
34
32
 
35
33
  The plugin does not upload data or expose a browser global by default. Reports
@@ -44,6 +42,11 @@ Enable only the output channels that match the environment:
44
42
 
45
43
  - Browser dev: use `browser.enabled: true` with a scoped reader such as
46
44
  `window.__FEDERATION__.__OBSERVABILITY__.host`.
45
+ - Chrome DevTools integration: use `devtools: true` together with browser
46
+ output so a browser extension can receive loading events through
47
+ `window.postMessage`.
48
+ - Agent-led browser dev: use `collector: true` to POST reports to the local
49
+ skill collector on `127.0.0.1:17891`.
47
50
  - Browser prod: set `browser.mode: "production"` so console output stays limited
48
51
  to `traceId` and known `errorCode`; export full reports only through explicit
49
52
  app-owned flows such as `exportReport()` or `onReport`.
@@ -68,7 +71,13 @@ Failure hints are printed with `console.error` so browser DevTools, CDP-based
68
71
  agents, Node logs, and log collection systems can detect that a Module
69
72
  Federation load failed and then use the printed `traceId` to fetch the full
70
73
  report. Successful or recovered reports are still available through the reader
71
- APIs and callbacks, but they are not promoted to console errors.
74
+ APIs and callbacks, but they are not promoted to console errors. When the
75
+ browser reader is enabled in development mode, the plugin prints a small
76
+ `console.info` line by default when a `loadRemote` or `loadShare` trace starts.
77
+ The line includes the `traceId` and read command so an agent can inspect pending
78
+ loading state before a timeout or error happens. In production browser mode,
79
+ start logs are disabled by default; set `trace.printStart: true` only when you
80
+ explicitly want them.
72
81
 
73
82
  The runtime only exposes the loading lifecycle hooks needed to know whether the
74
83
  main flow started, succeeded, or failed. This plugin listens to those hooks,
@@ -76,11 +85,22 @@ derives detailed reasons like shared version mismatch or eager boundary issues,
76
85
  and exposes the final loading state through a small `summary` object:
77
86
 
78
87
  - `runtime-loaded`: Module Federation finished loading the remote module.
79
- - `component-loaded`: business code called `markComponentLoaded`.
88
+ - `component-loaded`: business code called `markComponentLoaded`, or a producer
89
+ called the injected `onMFRemoteLoaded` callback.
90
+ - `preloaded`: `preloadRemote` finished loading the selected resources.
80
91
  - `failed`: the load failed and `failedPhase` points to the first specific
81
92
  failing phase.
82
93
  - `recovered`: loading hit an error but a fallback/recovery path returned a
83
- result.
94
+ result. For shared loading, the `custom-share-info-unmatched` reason means
95
+ build-time `customShareInfo` did not match a registered provider, but the
96
+ runtime handled it as a non-fatal result instead of a loading failure.
97
+
98
+ `summary.componentLoaded: false` only means no component-level ready signal was
99
+ observed. If `react.injectLoadedCallback: true` is enabled but this field is
100
+ still false, check whether the producer actually calls
101
+ `props.onMFRemoteLoaded?.(...)`. Without that producer call, the report can only
102
+ confirm that the remote resource loaded; it cannot prove whether the React
103
+ component reached the producer's business-ready point.
84
104
 
85
105
  For remote loading, the plugin listens to runtime lifecycle hooks such as
86
106
  `beforeRequest`, `afterMatchRemote`, `onLoad`, `afterLoadRemote`,
@@ -95,6 +115,20 @@ manifest, remoteEntry load, remoteEntry init, expose resolution, module factory
95
115
  execution, and final load completion. When a stage has matching start and end
96
116
  events, the end event includes a bounded `duration` value.
97
117
 
118
+ Preload reports include resource-level results from `preloadRemote`. Each
119
+ result records the resource URL, `resourceType`, `initiator`, preload `id`, and
120
+ status: `success`, `error`, `timeout`, or `cached`. Calls without `exposes` use
121
+ `remoteName/*` as the preload `id`. Calls with `exposes` are recorded per
122
+ expose as `remoteName/expose`. The plugin does not change the existing
123
+ `generatePreloadAssets` return shape; preload resources are still plain URL
124
+ arrays.
125
+
126
+ Runtime resource hooks also receive a `resourceContext` object on manifest,
127
+ remoteEntry, preload JS, and preload CSS resource loads. It contains
128
+ `initiator`, `id`, `resourceType`, and `url`, so custom loaders can tell whether
129
+ the resource was requested by `loadRemote` or `preloadRemote` without parsing
130
+ the URL.
131
+
98
132
  The report also keeps compact loading state under `summary`. It contains the
99
133
  final outcome, per-phase status and duration under `summary.phases`, safe
100
134
  cache/recovery markers under `summary.flags`, and the last resolved shared
@@ -110,20 +144,50 @@ a known runtime error code is present, and a short list of next checks. This is
110
144
  the field a person or AI coding agent should read first before falling back to
111
145
  the raw `events` timeline.
112
146
 
113
- For a stable report-reading and fixing workflow, see
114
- [`AI_TROUBLESHOOTING.md`](./AI_TROUBLESHOOTING.md). Codex-style agents can also
115
- use the repository's single `mf` skill entry with the `observability`
116
- sub-command.
147
+ For agent-led debugging, use the repository's single `mf` skill entry with the
148
+ `observability` sub-command. The skill is the maintained guide for reading
149
+ reports and deciding the next debugging step.
117
150
 
118
151
  `errorLoadShare` is used only for observation. Shared dependency miss, version
119
152
  mismatch, and eager boundary errors are not retried by the retry plugin by
120
153
  default because they are usually configuration or availability problems instead
121
- of transient network failures.
154
+ of transient network failures. When a build plugin supplies `customShareInfo`
155
+ and the runtime reports a handled miss, the observability report uses a
156
+ recovered outcome instead of marking the trace as failed.
157
+ The Chrome extension entry skips shared events for older or preview runtime
158
+ versions because those runtimes do not expose the same shared lifecycle
159
+ contract.
160
+
161
+ Business code can mark its own success condition with a fixed event. When React
162
+ callback injection is explicitly enabled, the wrapper injects an
163
+ `onMFRemoteLoaded` prop into the remote component. The producer can call it when
164
+ the component's own ready condition is met:
165
+
166
+ ```tsx
167
+ import { useEffect } from 'react';
168
+ import type { OnMFRemoteLoaded } from '@module-federation/observability-plugin';
169
+
170
+ export default function RemotePanel({ onMFRemoteLoaded }: { onMFRemoteLoaded?: OnMFRemoteLoaded }) {
171
+ useEffect(() => {
172
+ onMFRemoteLoaded?.({
173
+ metadata: {
174
+ dataReady: true,
175
+ },
176
+ });
177
+ }, [onMFRemoteLoaded]);
178
+
179
+ return <section>Remote panel</section>;
180
+ }
181
+ ```
122
182
 
123
- Business code can mark its own success condition with a fixed event:
183
+ If the app wants to mark readiness from the consumer side, it can still call the
184
+ instance method directly:
124
185
 
125
186
  ```ts
126
- observability.markComponentLoaded({
187
+ import { getInstance } from '@module-federation/runtime';
188
+ import '@module-federation/observability-plugin';
189
+
190
+ getInstance()?.markComponentLoaded({
127
191
  requestId: 'remote/Button',
128
192
  componentName: 'Button',
129
193
  metadata: {
@@ -132,9 +196,42 @@ observability.markComponentLoaded({
132
196
  });
133
197
  ```
134
198
 
135
- This records `component:business-loaded` on the same trace when possible.
199
+ Both paths record `component:business-loaded` on the same trace when possible.
136
200
  Business metadata is optional. String values keep their original details and are
137
- only length-limited, so user-provided metadata remains trustworthy.
201
+ only length-limited, so user-provided metadata remains trustworthy. The instance
202
+ method is attached when the observability plugin is registered. If an
203
+ application uses multiple runtime instances, call it on the instance that
204
+ registered this plugin.
205
+
206
+ React callback injection is available only when explicitly enabled:
207
+
208
+ ```ts
209
+ ObservabilityPlugin({
210
+ level: 'verbose',
211
+ react: {
212
+ injectLoadedCallback: true,
213
+ remoteIds: ['remote/Button'],
214
+ },
215
+ });
216
+ ```
217
+
218
+ When this option is enabled, the plugin tries to wrap remote function components
219
+ returned by `loadRemote`. The wrapper does not add DOM nodes. It injects the
220
+ `onMFRemoteLoaded` prop only. It does not observe React mount, render lifecycle,
221
+ or timeout. When the producer calls the callback, the report records
222
+ `component:business-loaded`. This option changes the component reference because
223
+ it returns a wrapper component, so use it as a temporary debugging switch and
224
+ remove it after the production issue is fixed.
225
+
226
+ If `summary.componentLoaded` is still `false` after enabling this option, inspect
227
+ the producer first. If the producer has not called `onMFRemoteLoaded`, the report
228
+ only proves remote runtime loading, not component business readiness. If the
229
+ producer source is unavailable, ask the producer owner to confirm whether the
230
+ callback was added.
231
+
232
+ Use `react.remoteIds` to limit this behavior to the remote requests you are
233
+ actively debugging. If `remoteIds` is empty, the plugin wraps detected React
234
+ function components loaded by the runtime instance that registered it.
138
235
 
139
236
  Browser output is available only when the plugin option explicitly enables it.
140
237
  When browser output is enabled, the report can be read from:
@@ -147,11 +244,84 @@ window.__FEDERATION__.__OBSERVABILITY__.host.findReports({ remote: 'remote1' });
147
244
  window.__FEDERATION__.__OBSERVABILITY__.host.exportReport('mf-trace-id');
148
245
  ```
149
246
 
150
- The same methods are available on the observability controller returned by
151
- `ObservabilityPlugin()`. `getReports({ limit })` returns recent reports newest
152
- first. `findReports()` can filter by `traceId`, `remote`, `expose`, `shared`,
153
- `status`, or `outcome`. `exportReport()` returns a copied report object, using
154
- the latest report when no `traceId` is provided.
247
+ Chrome DevTools panels can opt in to event delivery without polling the page:
248
+
249
+ ```ts
250
+ ObservabilityPlugin({
251
+ level: 'verbose',
252
+ browser: {
253
+ enabled: true,
254
+ scope: 'host',
255
+ mode: 'development',
256
+ },
257
+ trace: {
258
+ printStart: true,
259
+ },
260
+ devtools: true,
261
+ });
262
+ ```
263
+
264
+ This posts structured event/report snapshots to the page with
265
+ `window.postMessage`. Browser extensions can forward those messages from their
266
+ content script to the panel. The channel is disabled by default.
267
+
268
+ `getReports({ limit })` returns recent reports newest first. `findReports()` can
269
+ filter by `traceId`, `remote`, `expose`, `shared`, `status`, or `outcome`.
270
+ `exportReport()` returns a copied report object, using the latest report when no
271
+ `traceId` is provided.
272
+
273
+ For agent-led development debugging where a page may stay in a loading state,
274
+ enable the browser reader. Development browser mode prints start traces by
275
+ default:
276
+
277
+ ```ts
278
+ ObservabilityPlugin({
279
+ level: 'verbose',
280
+ browser: {
281
+ enabled: true,
282
+ scope: 'host',
283
+ },
284
+ });
285
+ ```
286
+
287
+ This prints only `loadRemote` and `loadShare` start lines. It does not print a
288
+ line for every internal phase. Set `trace.printStart: false` to disable it in
289
+ development browser mode. In production browser mode, set
290
+ `trace.printStart: true` to opt in.
291
+
292
+ If the agent cannot execute JavaScript in the browser page, enable the local
293
+ collector and start the collector from the MF skill:
294
+
295
+ ```ts
296
+ ObservabilityPlugin({
297
+ level: 'verbose',
298
+ collector: true,
299
+ });
300
+ ```
301
+
302
+ `collector: true` posts event/report snapshots to:
303
+
304
+ ```text
305
+ http://127.0.0.1:17891/__mf_observability
306
+ ```
307
+
308
+ Use a custom local port only when the default port is occupied:
309
+
310
+ ```ts
311
+ ObservabilityPlugin({
312
+ collector: {
313
+ enabled: true,
314
+ port: 17892,
315
+ },
316
+ });
317
+ ```
318
+
319
+ The runtime plugin does not create a server. The MF skill starts a temporary
320
+ local Node collector, writes reports under `.mf/observability/collector`, and
321
+ the agent reads those files. The collector path is local-only and does not
322
+ execute code or control the page. Collector delivery is controlled by the
323
+ `collector` option; debug mode only decides whether a failed collector request
324
+ prints a debug log.
155
325
 
156
326
  For browser production use, set `browser.mode: "production"` when the runtime
157
327
  console must stay minimal:
@@ -169,10 +339,10 @@ ObservabilityPlugin({
169
339
  In production browser mode, the `console.error` hint only includes the `traceId`
170
340
  and known `errorCode`. It does not print the report body, raw stack, request
171
341
  URL, or `read:` command. Full reports are still available only through explicit
172
- user choices such as the observability controller, `exportReport()`, or an
173
- application-owned `onReport` upload. Production applications that want richer
174
- observability should prefer `onReport` / `onEvent` to forward reports to their
175
- own telemetry system instead of exposing a public browser global.
342
+ user choices such as `exportReport()` or an application-owned `onReport` upload.
343
+ Production applications that want richer observability should prefer
344
+ `onReport` / `onEvent` to forward reports to their own telemetry system instead
345
+ of exposing a public browser global.
176
346
 
177
347
  Node file output is provided by the Node-specific entry:
178
348
 
@@ -180,15 +350,15 @@ Node file output is provided by the Node-specific entry:
180
350
  import { createInstance } from '@module-federation/runtime';
181
351
  import { ObservabilityPlugin } from '@module-federation/observability-plugin/node';
182
352
 
183
- const observability = ObservabilityPlugin({
184
- level: 'verbose',
185
- fileOutput: true,
186
- directory: '.mf/observability',
187
- });
188
-
189
353
  createInstance({
190
354
  name: 'host',
191
- plugins: [observability.plugin],
355
+ plugins: [
356
+ ObservabilityPlugin({
357
+ level: 'verbose',
358
+ fileOutput: true,
359
+ directory: '.mf/observability',
360
+ }),
361
+ ],
192
362
  remotes: [],
193
363
  });
194
364
  ```
@@ -293,3 +463,13 @@ Shared dependency reports include only evidence fields such as package name,
293
463
  share scope, requested version, available versions, selected provider, and a
294
464
  reason like `missing-provider`, `version-mismatch`, or `sync-async-boundary`.
295
465
  They do not include shared factories, module values, source, or business data.
466
+
467
+ Shared observability is intentionally scoped to the Module Federation instance
468
+ that resolved the shared dependency. It can answer which MF instance loaded a
469
+ shared package, which registered provider/version was selected, and the related
470
+ scope/version/eager configuration. It does not guarantee a causal link from that
471
+ shared dependency back to a specific remote or expose, because shared resolution
472
+ can be triggered later by the bundler runtime while chunks and module factories
473
+ execute. When multiple shared dependencies are involved, read all
474
+ `phase: "shared"` events. `summary.shared` is only a compact last-observed
475
+ summary.
@@ -0,0 +1,43 @@
1
+ # @module-federation/observability-plugin
2
+
3
+ ## 0.0.0-codex-node24-dev-node20-compat-ci-20260713063237
4
+
5
+ ### Patch Changes
6
+
7
+ - @module-federation/sdk@0.0.0-codex-node24-dev-node20-compat-ci-20260713063237
8
+
9
+ ## 2.5.3
10
+
11
+ ### Patch Changes
12
+
13
+ - Updated dependencies [dcc640b]
14
+ - Updated dependencies [9958086]
15
+ - @module-federation/sdk@2.7.0
16
+
17
+ ## 2.5.2
18
+
19
+ ### Patch Changes
20
+
21
+ - @module-federation/sdk@2.6.0
22
+
23
+ ## 2.5.1
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies [b9b3b8c]
28
+ - @module-federation/sdk@2.5.1
29
+
30
+ ## 2.5.0
31
+
32
+ ### Minor Changes
33
+
34
+ - 41281f4: Add a Loading Trace panel that can configure and inject the observability plugin, reload the inspected page, stream loading events, and export collected reports.
35
+ - 41281f4: Add an opt-in observability plugin, a Chrome-extension-safe observability plugin entry with an independent name and fixed browser scope, a direct runtime plugin API with instance-bound component loaded marks, explicit temporary React `onMFRemoteLoaded` callback injection for matched remotes, opt-in start console traces for `loadRemote` and `loadShare`, a local collector mode for AI-assisted browser debugging, a Node-specific export for file reports, a build-specific export for build summaries and build error reports, remote and shared lifecycle hooks, console trace hints, safe browser/Node report outputs, configurable error stack capture with explicit console raw-stack opt-ins, shared/eager loading evidence gated to stable runtime `2.5.0+` for Chrome-extension compatibility, final loading outcome summaries for Module Federation loading reports including resolved shared dependencies, deterministic fact reports for runtime and build failures, no-op return handling for observer hooks, detailed remote match/init/expose/factory phase events with phase durations, compact phase summaries, cache/fallback markers, loaded-before evidence from existing federation instances when a remote load fails, length-limited business component metadata, clipped moduleInfo evidence with preserved deployment locator fields for snapshot-dependent failures, normalized runtime error summaries with error codes, owner hints, retryability, and safe context, dedicated runtime error codes for invalid manifests, missing exposes, and remote container init failures, plus MF skill guidance for reading and fixing observability reports.
36
+
37
+ ### Patch Changes
38
+
39
+ - 0716c11: Track preload resource results and expose resource context to loader hooks.
40
+ - 328542c: Send configured local collector events outside debug mode while keeping failures quiet unless debug logging is enabled.
41
+ - Updated dependencies [5d4095d]
42
+ - Updated dependencies [0716c11]
43
+ - @module-federation/sdk@2.5.0