@ebay/muse-lib-react 1.3.5 → 2.0.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.
Files changed (58) hide show
  1. package/MUSE_README.md +370 -0
  2. package/build/MUSE_README.md +252 -503
  3. package/build/dev/assets/_muse-virtual-entry-jqLrDl9I.css +1 -0
  4. package/build/dev/deps-manifest.json +6 -0
  5. package/build/dev/index.html +34 -0
  6. package/build/dev/info.json +15 -0
  7. package/build/dev/lib-manifest.json +1861 -2547
  8. package/build/dev/main.js +320 -75585
  9. package/build/dev/main.js.map +1 -1
  10. package/build/dist/assets/_muse-virtual-entry-jqLrDl9I.css +1 -0
  11. package/build/dist/deps-manifest.json +6 -0
  12. package/build/dist/index.html +34 -0
  13. package/build/dist/info.json +15 -0
  14. package/build/dist/lib-manifest.json +1794 -2727
  15. package/build/dist/main.js +111 -3
  16. package/build/dist/main.js.map +1 -1
  17. package/build/test/assets/_muse-virtual-entry-jqLrDl9I.css +1 -0
  18. package/build/test/deps-manifest.json +6 -0
  19. package/build/test/index.html +34 -0
  20. package/build/test/info.json +15 -0
  21. package/build/test/lib-manifest.json +1801 -2718
  22. package/build/test/main.js +111 -3
  23. package/build/test/main.js.map +1 -1
  24. package/package.json +41 -43
  25. package/src/a.json +3 -0
  26. package/src/common/configStore.js +9 -8
  27. package/src/features/common/HelloWorld.jsx +14 -0
  28. package/src/features/common/Test1.jsx +12 -0
  29. package/src/features/common/index.js +1 -0
  30. package/src/features/common/route.js +7 -0
  31. package/src/features/sub-app/{LoadingSkeleton.js → LoadingSkeleton.jsx} +1 -2
  32. package/build/dev/asset-manifest.json +0 -11
  33. package/build/dev/muse.d.ts +0 -170
  34. package/build/dev/static/media/subAppLoading2.bf08007b83457287ade1cedb71bc70f7.svg +0 -7
  35. package/build/dist/asset-manifest.json +0 -11
  36. package/build/dist/main.js.LICENSE.txt +0 -125
  37. package/build/dist/muse.d.ts +0 -170
  38. package/build/dist/static/media/subAppLoading2.bf08007b83457287ade1cedb71bc70f7.svg +0 -7
  39. package/build/test/asset-manifest.json +0 -11
  40. package/build/test/main.js.LICENSE.txt +0 -125
  41. package/build/test/muse.d.ts +0 -170
  42. package/build/test/static/media/subAppLoading2.bf08007b83457287ade1cedb71bc70f7.svg +0 -7
  43. /package/build/dev/{static/media/logo.b23b880b0dac2229042c.png → assets/logo-V3RbDVED.png} +0 -0
  44. /package/build/dist/{static/media/logo.b23b880b0dac2229042c.png → assets/logo-V3RbDVED.png} +0 -0
  45. /package/build/test/{static/media/logo.b23b880b0dac2229042c.png → assets/logo-V3RbDVED.png} +0 -0
  46. /package/src/{Root.js → Root.jsx} +0 -0
  47. /package/src/common/{routeConfig.js → routeConfig.jsx} +0 -0
  48. /package/src/features/common/{ErrorBoundary.js → ErrorBoundary.jsx} +0 -0
  49. /package/src/features/common/{Nodes.js → Nodes.jsx} +0 -0
  50. /package/src/features/common/{PageNotFound.js → PageNotFound.jsx} +0 -0
  51. /package/src/features/common/{useExtPoint.js → useExtPoint.jsx} +0 -0
  52. /package/src/features/home/{App.js → App.jsx} +0 -0
  53. /package/src/features/home/{Homepage.js → Homepage.jsx} +0 -0
  54. /package/src/features/sub-app/{C2SProxyFailed.js → C2SProxyFailed.jsx} +0 -0
  55. /package/src/features/sub-app/{FixedSubAppContainer.js → FixedSubAppContainer.jsx} +0 -0
  56. /package/src/features/sub-app/{SubAppContainer.js → SubAppContainer.jsx} +0 -0
  57. /package/src/features/sub-app/{route.js → route.jsx} +0 -0
  58. /package/src/{index.js → index.jsx} +0 -0
package/MUSE_README.md ADDED
@@ -0,0 +1,370 @@
1
+ # Plugin Integration Guide: @ebay/muse-lib-react
2
+
3
+ **Generated**: 2026-05-21
4
+ **Plugin Type**: lib
5
+
6
+ ---
7
+
8
+ ## 1. Plugin Purpose & Overview
9
+
10
+ ### What This Plugin Does
11
+
12
+ `@ebay/muse-lib-react` is the foundational React lib plugin for the MUSE micro-frontends framework. It bootstraps the React application (creates the React DOM root and renders the app), assembles the provider stack (Redux, React Query, React Router, NiceModal, SubApp context), builds the route tree from contributions across all plugins, and combines Redux reducers from all loaded plugins into a single store.
13
+
14
+ ### Key Features
15
+
16
+ - **App bootstrapping** — Creates and renders the React root into `#muse-react-root` on demand, invokes lifecycle hooks before and after render.
17
+ - **Provider stack** — Builds the ordered React provider chain (React Query → Redux → SubApp Context → NiceModal → Router) and makes it extensible via extension points.
18
+ - **Route assembly** — Collects route definitions from all loaded plugins, normalizes absolute/parent routes, resolves the homepage component, and renders with React Router v7.
19
+ - **Redux store** — Combines built-in reducers with plugin-contributed reducers (both plugin-scoped and root-level).
20
+ - **Shared module exports** — Bundles React ecosystem libraries (React Router, React Query, lodash, react-use, react-loadable) so all normal plugins can use them without duplicating them in their own bundles.
21
+ - **Utility primitives** — Exports `extendArray`, `useExtPoint`, and `Nodes` to help other plugins build their own extensible arrays and UI node lists.
22
+
23
+ ### Plugin Type: lib
24
+
25
+ As a `lib` plugin with `muse.isAppEntry: true`, this plugin loads before all normal plugins and serves two roles: it **provides shared runtime modules** (React, Redux, React Router, etc.) to every normal plugin via the MUSE build system's module federation, and it **acts as the application entry point** that renders the React tree. Normal plugins must never bundle these libraries themselves; they receive them from this plugin at runtime.
26
+
27
+ ---
28
+
29
+ ## 2. Extension Points Exposed
30
+
31
+ This plugin exposes the following extension points that other plugins can implement to extend its functionality.
32
+
33
+ ### Summary
34
+
35
+ - **Total Extension Points**: 15
36
+ - **Categories**: Root Lifecycle, Provider Stack, Routing, Redux, App Shell, Utility
37
+
38
+ ### Extension Point List
39
+
40
+ #### `root.beforeRender`
41
+
42
+ - **Purpose**: Execute initialization logic before the React root is created and rendered. Use this for side effects that must complete before any React component mounts.
43
+ - **When Invoked**: Synchronously before `createRoot().render()` is called.
44
+ - **Context Parameters**: none
45
+ - **Expected Return**: ignored
46
+ - **Use Case Example**: Injecting global CSS variables, initializing an analytics library, or pre-fetching critical configuration.
47
+ - **File Reference**: `src/index.jsx:26`
48
+
49
+ #### `root.afterRender`
50
+
51
+ - **Purpose**: Execute logic immediately after `root.render()` is called (before React has painted).
52
+ - **When Invoked**: Synchronously after `root.render(<Root />)`.
53
+ - **Context Parameters**: none
54
+ - **Expected Return**: ignored
55
+ - **Use Case Example**: Starting a performance measurement timer or notifying a loading screen manager.
56
+ - **File Reference**: `src/index.jsx:31`
57
+
58
+ #### `onReady`
59
+
60
+ - **Purpose**: Execute logic after the application is fully mounted to the DOM.
61
+ - **When Invoked**: After `root.afterRender`, still synchronous on the same tick.
62
+ - **Context Parameters**: none
63
+ - **Expected Return**: ignored
64
+ - **Use Case Example**: Hiding a static HTML splash screen, signalling to an E2E test harness that the app is ready.
65
+ - **File Reference**: `src/index.jsx:33`
66
+
67
+ #### `root.renderChildren`
68
+
69
+ - **Purpose**: Wrap the rendered route tree in additional React components. Each implementer receives the current children and must return the (potentially wrapped) children.
70
+ - **When Invoked**: During `Root` render, before the provider chain is built.
71
+ - **Context Parameters**: `children` — `React.ReactNode` — the current route element tree
72
+ - **Expected Return**: `React.ReactNode` — the (wrapped or unchanged) children
73
+ - **Use Case Example**: Wrapping the entire app in an error boundary, a theme context, or a drag-and-drop context.
74
+ - **File Reference**: `src/Root.jsx:104`
75
+
76
+ #### `routerProps`
77
+
78
+ - **Purpose**: Merge additional props directly into the `RouterProvider` component.
79
+ - **When Invoked**: During `Root` render, when the Router is configured.
80
+ - **Context Parameters**: none
81
+ - **Expected Return**: `Record<string, any>` — props merged into `RouterProvider`. Only the first contribution is used.
82
+ - **Use Case Example**: Providing a custom `future` flag object for React Router v7 feature flags.
83
+ - **File Reference**: `src/Root.jsx:140`
84
+
85
+ #### `root.preProcessProviders`
86
+
87
+ - **Purpose**: Inspect or mutate the initial providers array before additional providers from `root.getProviders` are added. Use this to remove or reorder built-in providers.
88
+ - **When Invoked**: During `Root` render, via `extendArray` before provider collection.
89
+ - **Context Parameters**: `{ providers: ProviderType[] }` — the current mutable array of built-in providers
90
+ - **Expected Return**: `string | boolean` — return value is used by `jsPlugin.sort` ordering
91
+ - **Use Case Example**: Removing the built-in Redux `Provider` to replace it with a custom store setup.
92
+ - **File Reference**: `src/Root.jsx:181`, `src/utils.js:17`
93
+
94
+ #### `root.getProviders`
95
+
96
+ - **Purpose**: Contribute one or more additional React context providers to be inserted into the provider stack at a specific order position.
97
+ - **When Invoked**: During `Root` render, via `extendArray` during provider collection.
98
+ - **Context Parameters**: `{ providers: ProviderType[] }` — the current providers array (after pre-processing)
99
+ - **Expected Return**: `ProviderType | ProviderType[] | void` — provider descriptor(s) to add
100
+ - **Use Case Example**: Adding an Apollo Client provider at `order: 25` (between Redux and SubApp context).
101
+ - **File Reference**: `src/Root.jsx:181`, `src/utils.js:18`
102
+
103
+ #### `root.processProviders`
104
+
105
+ - **Purpose**: Post-process the combined providers array after all `getProviders` contributions have been collected.
106
+ - **When Invoked**: During `Root` render, via `extendArray` after collection.
107
+ - **Context Parameters**: `{ providers: ProviderType[] }` — the full combined providers array
108
+ - **Expected Return**: `string | void` — used for sort ordering
109
+ - **Use Case Example**: Validating that required providers are present and throwing a descriptive error if not.
110
+ - **File Reference**: `src/Root.jsx:181`, `src/utils.js:20`
111
+
112
+ #### `root.postProcessProviders`
113
+
114
+ - **Purpose**: Final hook to inspect or modify the providers array after all processing is complete.
115
+ - **When Invoked**: During `Root` render, via `extendArray` as the last step.
116
+ - **Context Parameters**: `{ providers: ProviderType[] }` — the finalized providers array
117
+ - **Expected Return**: `void`
118
+ - **Use Case Example**: Logging the final provider stack in development for debugging.
119
+ - **File Reference**: `src/Root.jsx:181`, `src/utils.js:21`
120
+
121
+ #### `route`
122
+
123
+ - **Purpose**: Register one or more route definitions into the application's route tree.
124
+ - **When Invoked**: On every render of the `Root` component, when `routeConfig()` rebuilds the route tree.
125
+ - **Context Parameters**: none
126
+ - **Expected Return**: `MuseRoute | MuseRoute[]` — one or more route objects. See `MuseRoute` in `src/muse.d.ts:89`.
127
+ - **Use Case Example**: Adding `/settings`, `/reports`, or any feature page routes.
128
+ - **File Reference**: `src/common/routeConfig.jsx:87`
129
+
130
+ #### `home.homepage`
131
+
132
+ - **Purpose**: Replace the default homepage component rendered at the root path `/`.
133
+ - **When Invoked**: During route assembly in `routeConfig()`.
134
+ - **Context Parameters**: none
135
+ - **Expected Return**: `ComponentType` — the React component to render at `/`. Only one plugin should contribute this.
136
+ - **Use Case Example**: A dashboard plugin providing a `DashboardHomepage` component.
137
+ - **File Reference**: `src/common/routeConfig.jsx:96`
138
+
139
+ #### `home.mainLayout`
140
+
141
+ - **Purpose**: Provide the main layout shell component that wraps all page content. Only one plugin should contribute this — multiple contributions render an error message.
142
+ - **When Invoked**: On every render of the `App` shell component.
143
+ - **Context Parameters**: none
144
+ - **Expected Return**: `ComponentType` — a layout component that accepts `children`. Only the first contribution is used.
145
+ - **Use Case Example**: `muse-layout-antd` provides a sidebar/header layout via this extension point.
146
+ - **File Reference**: `src/features/home/App.jsx:10`
147
+
148
+ #### `rootComponent`
149
+
150
+ - **Purpose**: Mount an invisible initialization React component into the app root. The component should return `null` — it exists only for side effects (subscriptions, global listeners, etc.).
151
+ - **When Invoked**: On every render of the `App` shell component.
152
+ - **Context Parameters**: none
153
+ - **Expected Return**: `ComponentType` — a component that renders `null`. All contributing plugins' components are rendered simultaneously.
154
+ - **Use Case Example**: A plugin that listens for global WebSocket messages and dispatches Redux actions.
155
+ - **File Reference**: `src/features/home/App.jsx:7`
156
+
157
+ #### `reducer`
158
+
159
+ - **Purpose**: Contribute a plugin-scoped Redux reducer. The reducer is automatically mounted under the key `plugin-<pluginName>` (camelCased) in the store.
160
+ - **When Invoked**: When the Redux store is created (once at startup).
161
+ - **Context Parameters**: none
162
+ - **Expected Return**: `Reducer<any, AnyAction>` — a Redux reducer function
163
+ - **Use Case Example**: A plugin contributing its own Redux slice under `pluginMyPlugin` in the store.
164
+ - **File Reference**: `src/common/rootReducer.js:24`
165
+
166
+ #### `reducers`
167
+
168
+ - **Purpose**: Contribute one or more root-level Redux reducers with custom store branch keys (unlike `reducer` which auto-generates the key).
169
+ - **When Invoked**: When the Redux store is created (once at startup).
170
+ - **Context Parameters**: none
171
+ - **Expected Return**: `Record<string, Reducer<any, AnyAction>>` — a map of store key → reducer
172
+ - **Use Case Example**: A plugin that needs its state at `store.auth` or `store.featureFlags` instead of an auto-generated key.
173
+ - **File Reference**: `src/common/rootReducer.js:33`
174
+
175
+ ### Usage Example
176
+
177
+ ```javascript
178
+ // Extension points use nested object properties — NOT string paths
179
+ plugin.register({
180
+ name: 'my-plugin',
181
+
182
+ // Lifecycle hooks
183
+ onReady: () => {
184
+ console.log('App is ready');
185
+ },
186
+
187
+ // Route contribution
188
+ route: [
189
+ { path: 'settings', component: SettingsPage },
190
+ { path: 'reports', component: ReportsPage },
191
+ ],
192
+
193
+ // Redux reducer
194
+ reducer: myPluginReducer,
195
+
196
+ // Provider injection
197
+ root: {
198
+ getProviders: ({ providers }) => ({
199
+ order: 25,
200
+ key: 'my-context',
201
+ provider: MyContextProvider,
202
+ props: { value: myContextValue },
203
+ }),
204
+ beforeRender: () => {
205
+ initAnalytics();
206
+ },
207
+ },
208
+
209
+ // Layout/homepage
210
+ home: {
211
+ homepage: MyHomepageComponent,
212
+ mainLayout: MyLayoutComponent, // WARNING: only one plugin should provide this
213
+ },
214
+
215
+ // Invisible init component
216
+ rootComponent: MyGlobalListenerComponent,
217
+ });
218
+ ```
219
+
220
+ ---
221
+
222
+ ## 3. Extension Points Contributed
223
+
224
+ This plugin does not extend other plugins via extension points. It is the foundational bootstrap plugin — it only **exposes** extension points for others to implement.
225
+
226
+ ---
227
+
228
+ ## 4. Exported Functionality
229
+
230
+ This plugin exports the following functionality for use by other plugins.
231
+
232
+ **Access via**: Shared modules are available automatically in normal plugins via the MUSE build system. Direct exports are accessible via `plugin.getPlugin('@ebay/muse-lib-react').exports` or direct source imports.
233
+
234
+ ### Shared Modules (Module Federation)
235
+
236
+ As a `lib` plugin, `@ebay/muse-lib-react` makes the following libraries available as shared singletons to all normal plugins at runtime. Normal plugins must **not** bundle these themselves — they receive them from this plugin via the MUSE vite/webpack build plugin.
237
+
238
+ The shared module set is determined by the transitive imports of `src/index.jsx`. The following are explicitly re-exported:
239
+
240
+ | Shared Module | Package | Version | Export Key |
241
+ |---|---|---|---|
242
+ | `Loadable` | `react-loadable` | 5.5.0 | `Loadable` |
243
+ | `_` (lodash) | `lodash` | 4.18.1 | `_` |
244
+ | `reactUse` | `react-use` | 17.6.0 | `reactUse` |
245
+ | `reactRouterDom` | `react-router-dom` | 7.15.0 | `reactRouterDom` |
246
+ | `reactQuery` | `@tanstack/react-query` | 5.100.9 | `reactQuery` |
247
+
248
+ Additionally, all transitive dependencies (including `react`, `react-dom`, `redux`, `react-redux`, `@ebay/nice-modal-react`, `history`) are shared automatically by the MUSE build system.
249
+
250
+ **File Reference**: `src/index.jsx:41`
251
+
252
+ ### Utilities
253
+
254
+ #### `extendArray(arr, extName, extBase, ...args)`
255
+
256
+ Makes any array extensible by js-plugin extension points. Invokes four lifecycle hooks in order — `preProcess<Name>`, `get<Name>`, `process<Name>`, `postProcess<Name>` — then sorts the array by `order`.
257
+
258
+ - **Parameters**: `arr` (mutable array), `extName` (string, capitalized to form hook names), `extBase` (string prefix for hook names), `...args` (passed through to each hook invocation)
259
+ - **Returns**: the mutated `arr`
260
+ - **File Reference**: `src/utils.js:15`
261
+
262
+ ### React Hooks
263
+
264
+ #### `useExtPoint(extPointName, extArgs)`
265
+
266
+ A React hook that invokes any extension point and renders all contributed components into a JSX fragment. Returns `{ extNode, values }` where `extNode` is the rendered fragment of all contributions and `values` is state updated when a contribution calls its `callback` prop.
267
+
268
+ - **Parameters**: `extPointName` (string), `extArgs` (object passed as props to each contributed component)
269
+ - **Returns**: `{ extNode: ReactNode, values: any[] }`
270
+ - **File Reference**: `src/features/common/useExtPoint.jsx:7`
271
+
272
+ ### React Components
273
+
274
+ #### `Nodes`
275
+
276
+ Renders an extensible list of nodes where each node can be a render function, raw content, or component. Internally uses `extendArray` to allow other plugins to inject items.
277
+
278
+ - **Props**: `items` (array), `extName` (string), `extBase` (string), `extArgs` (object)
279
+ - **File Reference**: `src/features/common/Nodes.jsx:8`
280
+
281
+ ### Using Shared Modules
282
+
283
+ In normal plugins built with `@ebay/muse-vite-plugin` or `@ebay/muse-webpack-plugin`, these modules are automatically externalized and resolved from `@ebay/muse-lib-react` at runtime:
284
+
285
+ ```javascript
286
+ // In a normal plugin — these are resolved from muse-lib-react at runtime,
287
+ // NOT bundled into the plugin's own bundle.
288
+ import { useNavigate, Link } from 'react-router-dom';
289
+ import { useQuery } from '@tanstack/react-query';
290
+ import _ from 'lodash';
291
+ ```
292
+
293
+ **Note**: Exports create tight coupling. Prefer extension points for loose coupling when possible.
294
+
295
+ ---
296
+
297
+ ## 5. Consumed Exports (Runtime Dependencies)
298
+
299
+ This plugin does not consume exports from other plugins. All inter-plugin collaboration is done through extension points (loose coupling).
300
+
301
+ ---
302
+
303
+ ## 6. Integration Examples
304
+
305
+ ### Extending This Plugin
306
+
307
+ ```javascript
308
+ // Extension points use nested object properties — NOT string paths
309
+ plugin.register({
310
+ name: 'my-plugin',
311
+
312
+ // Add application routes
313
+ route: [
314
+ { path: 'my-feature', component: MyFeaturePage },
315
+ ],
316
+
317
+ // Redux integration
318
+ reducer: myFeatureReducer,
319
+
320
+ // Root lifecycle
321
+ onReady: () => {
322
+ console.log('App mounted');
323
+ },
324
+
325
+ // Provider injection
326
+ root: {
327
+ getProviders: ({ providers }) => ({
328
+ order: 25,
329
+ key: 'my-context',
330
+ provider: MyContextProvider,
331
+ props: { store: myStore },
332
+ }),
333
+ },
334
+
335
+ // Layout/homepage
336
+ home: {
337
+ homepage: MyHomepageComponent,
338
+ mainLayout: MyLayoutComponent, // WARNING: only one plugin should provide this
339
+ },
340
+
341
+ // Invisible init component
342
+ rootComponent: MyGlobalListenerComponent,
343
+ });
344
+ ```
345
+
346
+ ### Building Your Own Extensible Array
347
+
348
+ ```javascript
349
+ import { extendArray } from '@ebay/muse-lib-react/src/utils';
350
+
351
+ // In your component:
352
+ const menuItems = [...defaultItems];
353
+ extendArray(menuItems, 'menuItems', 'myPlugin', { context: someContext });
354
+ // Now other plugins can implement:
355
+ // myPlugin.preProcessMenuItems
356
+ // myPlugin.getMenuItems (return additional items)
357
+ // myPlugin.processMenuItems
358
+ // myPlugin.postProcessMenuItems
359
+ ```
360
+
361
+ ### Using the useExtPoint Hook
362
+
363
+ ```javascript
364
+ import useExtPoint from '@ebay/muse-lib-react/src/features/common/useExtPoint';
365
+
366
+ function MyToolbar() {
367
+ const { extNode } = useExtPoint('myPlugin.toolbarItems', { context: 'main' });
368
+ return <div className="toolbar">{extNode}</div>;
369
+ }
370
+ ```