@linagora/linid-im-front-corelib 0.0.6 β 0.0.8
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/README.md +3 -3
- package/dist/core-lib.es.js +3 -2
- package/dist/core-lib.umd.js +3 -3
- package/dist/package.json +13 -9
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/dist/types/src/index.d.ts +2 -1
- package/package.json +13 -9
- package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -83
- package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -90
- package/.github/ISSUE_TEMPLATE/question.yml +0 -31
- package/.github/ISSUE_TEMPLATE/security.yml +0 -69
- package/.github/actions/setup-node-pnpm/action.yml +0 -29
- package/.github/workflows/pull-request.yml +0 -147
- package/.github/workflows/release.yml +0 -90
- package/.prettierignore +0 -7
- package/.prettierrc.json +0 -5
- package/.vscode/extensions.json +0 -3
- package/.vscode/settings.json +0 -9
- package/CHANGELOG.md +0 -51
- package/CONTRIBUTING.md +0 -269
- package/COPYRIGHT +0 -23
- package/docs/components-plugin-zones.md +0 -168
- package/docs/helpers.md +0 -188
- package/docs/module-lifecycle.md +0 -717
- package/docs/services.md +0 -39
- package/docs/types-and-interfaces.md +0 -139
- package/eslint.config.js +0 -136
- package/src/components/LinidZoneRenderer.vue +0 -77
- package/src/index.ts +0 -62
- package/src/lifecycle/skeleton.ts +0 -147
- package/src/services/federationService.ts +0 -44
- package/src/services/httpClientService.ts +0 -61
- package/src/services/linIdConfigurationService.ts +0 -73
- package/src/stores/linIdConfigurationStore.ts +0 -116
- package/src/stores/linidZoneStore.ts +0 -62
- package/src/types/linidConfiguration.ts +0 -70
- package/src/types/linidZone.ts +0 -48
- package/src/types/module.ts +0 -96
- package/src/types/moduleLifecycle.ts +0 -154
- package/tests/unit/components/LinidZoneRenderer.spec.js +0 -135
- package/tests/unit/lifecycle/skeleton.spec.js +0 -138
- package/tests/unit/services/federationService.spec.js +0 -146
- package/tests/unit/services/httpClientService.spec.js +0 -49
- package/tests/unit/services/linIdConfigurationService.spec.js +0 -113
- package/tests/unit/stores/linIdConfigurationStore.spec.js +0 -171
- package/tests/unit/stores/linidZoneStore.spec.js +0 -94
- package/tsconfig.json +0 -14
- package/tsconfig.lib.json +0 -20
- package/tsconfig.node.json +0 -9
- package/tsconfig.spec.json +0 -16
- package/vite.config.ts +0 -37
- package/vitest.config.ts +0 -19
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
# LinidZoneRenderer Component π
|
|
2
|
-
|
|
3
|
-
The **LinidZoneRenderer** component is a core feature of `linid-im-front-corelib`.
|
|
4
|
-
It allows the host application to **dynamically render remote Vue components (plugins)** inside predefined βzonesβ of the UI.
|
|
5
|
-
|
|
6
|
-
This component works together with the **Linid Zone Store**, which manages plugin registration and provides reactive updates.
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## π― Purpose
|
|
11
|
-
|
|
12
|
-
LinidZoneRenderer provides:
|
|
13
|
-
|
|
14
|
-
- **Dynamic rendering:** Components are loaded asynchronously only when needed.
|
|
15
|
-
- **Reactive updates:** New plugins registered to a zone appear automatically.
|
|
16
|
-
- **Extensibility:** New features can be added via plugins without modifying the host app.
|
|
17
|
-
- **Standardization:** All plugins follow the `LinidZoneEntry` interface.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## π§± How to Use the Component
|
|
22
|
-
|
|
23
|
-
### Basic Usage
|
|
24
|
-
|
|
25
|
-
```vue
|
|
26
|
-
<template>
|
|
27
|
-
<LinidZoneRenderer zone="user-details" />
|
|
28
|
-
</template>
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
* `zone` (string): Identifier of the zone where components should be rendered.
|
|
32
|
-
* The component automatically fetches all registered plugins for this zone from the store and renders them asynchronously.
|
|
33
|
-
|
|
34
|
-
### Props
|
|
35
|
-
|
|
36
|
-
| Prop | Type | Description |
|
|
37
|
-
| ---------- | ------------- | -------------------------------------------------- |
|
|
38
|
-
| `zone` | string | The name of the zone to render |
|
|
39
|
-
|
|
40
|
-
### Default Slot - Fallback Component
|
|
41
|
-
|
|
42
|
-
The `LinidZoneRenderer` component provides a **default slot** that is displayed when no components are registered in the specified zone **after loading is complete**.
|
|
43
|
-
|
|
44
|
-
#### Purpose
|
|
45
|
-
|
|
46
|
-
The default slot allows you to:
|
|
47
|
-
- Display a custom message when a zone is empty
|
|
48
|
-
- Render a placeholder component
|
|
49
|
-
- Show alternative content for zones without plugins
|
|
50
|
-
|
|
51
|
-
#### Behavior
|
|
52
|
-
|
|
53
|
-
The slot is rendered **only when**:
|
|
54
|
-
1. β
The loading process is complete
|
|
55
|
-
2. β
No components are registered in the zone
|
|
56
|
-
|
|
57
|
-
**Important:** The slot will **not** be displayed during the initial loading phase to avoid flickering.
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
#### Usage
|
|
62
|
-
|
|
63
|
-
##### Default Fallback (No Custom Slot)
|
|
64
|
-
|
|
65
|
-
If you don't provide a custom slot, the component displays a default message:
|
|
66
|
-
|
|
67
|
-
```vue
|
|
68
|
-
<template>
|
|
69
|
-
<LinidZoneRenderer zone="sidebar" />
|
|
70
|
-
</template>
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**Rendered when zone is empty:**
|
|
74
|
-
```html
|
|
75
|
-
<div>No components to render in this zone.</div>
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
---
|
|
79
|
-
|
|
80
|
-
##### Custom Fallback Component
|
|
81
|
-
|
|
82
|
-
You can provide your own fallback content using the default slot:
|
|
83
|
-
|
|
84
|
-
```vue
|
|
85
|
-
<template>
|
|
86
|
-
<LinidZoneRenderer zone="user-actions">
|
|
87
|
-
<template #default>
|
|
88
|
-
<div>
|
|
89
|
-
<p>No actions available for this user.</p>
|
|
90
|
-
</div>
|
|
91
|
-
</template>
|
|
92
|
-
</LinidZoneRenderer>
|
|
93
|
-
</template>
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## β‘ Adding a Plugin with the Store
|
|
99
|
-
|
|
100
|
-
Plugins must be registered in the **Linid Zone Store** before they can be rendered.
|
|
101
|
-
|
|
102
|
-
```ts
|
|
103
|
-
import { useLinidZoneStore } from '@linagora/linid-im-front-corelib';
|
|
104
|
-
|
|
105
|
-
const linidZoneStore = useLinidZoneStore();
|
|
106
|
-
|
|
107
|
-
linidZoneStore.register("user-details", {
|
|
108
|
-
plugin: "@/remote/UserCard",
|
|
109
|
-
props: { userId: 42 },
|
|
110
|
-
});
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
* `plugin`: Path or identifier of the remote component to load.
|
|
114
|
-
* `props`: Optional props passed to the plugin component.
|
|
115
|
-
|
|
116
|
-
> Once registered, the `LinidZoneRenderer` component will automatically render this plugin in the specified zone.
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## π§© How It Works
|
|
121
|
-
|
|
122
|
-
1. The component retrieves all entries for the given `zone` from the **Linid Zone Store**.
|
|
123
|
-
2. Each entry is wrapped as an **async component** retrieved from its remote module using the `loadAsyncComponent(entry.plugin)` method.
|
|
124
|
-
3. All plugins in the zone are rendered sequentially with:
|
|
125
|
-
|
|
126
|
-
```vue
|
|
127
|
-
<component :is="entry.component" v-bind="entry.props" />
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
* This allows multiple plugins to coexist in a single zone.
|
|
131
|
-
* The component reacts automatically to changes in the store.
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## π§ Plugin Types
|
|
136
|
-
|
|
137
|
-
Plugins must implement the `LinidZoneEntry` interface:
|
|
138
|
-
|
|
139
|
-
```ts
|
|
140
|
-
export interface LinidZoneEntry {
|
|
141
|
-
/** Path to the remote module */
|
|
142
|
-
plugin: string;
|
|
143
|
-
|
|
144
|
-
/** Props forwarded to the plugin component */
|
|
145
|
-
props?: Record<string, unknown>;
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
* Props are automatically forwarded to the dynamically loaded component.
|
|
150
|
-
* Components are wrapped in `loadAsyncComponent` for asynchronous loading.
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
## β
Advantages
|
|
155
|
-
|
|
156
|
-
* **Decoupled architecture:** Plugins are independent of the host.
|
|
157
|
-
* **Lazy loading:** Only load components when needed.
|
|
158
|
-
* **Reactive:** Supports runtime addition/removal of plugins.
|
|
159
|
-
* **Standardized interface:** All plugins conform to `LinidZoneEntry`.
|
|
160
|
-
* **Framework-friendly:** Works natively with Vue 3, Pinia, and Module Federation.
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
## π Notes
|
|
165
|
-
|
|
166
|
-
* Multiple plugins can be registered for the same zone; they are rendered in registration order.
|
|
167
|
-
* Failed imports are handled automatically; you can provide a `fallback` component.
|
|
168
|
-
* Designed for scalable front-end applications using Module Federation.
|
package/docs/helpers.md
DELETED
|
@@ -1,188 +0,0 @@
|
|
|
1
|
-
# Helper Functions
|
|
2
|
-
|
|
3
|
-
This document describes utility functions provided by `linid-im-front-corelib` to simplify common tasks.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## `loadAsyncComponent`
|
|
8
|
-
|
|
9
|
-
Loads a remote Vue component from a Module Federation remote using the enhanced runtime.
|
|
10
|
-
|
|
11
|
-
This helper wraps Vue's `defineAsyncComponent` and Module Federation's `loadRemote` to provide a simple way to load federated components asynchronously.
|
|
12
|
-
|
|
13
|
-
### Import
|
|
14
|
-
|
|
15
|
-
```typescript
|
|
16
|
-
import { loadAsyncComponent } from '@linagora/linid-im-front-corelib';
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
### Parameters
|
|
20
|
-
|
|
21
|
-
| Parameter | Type | Description |
|
|
22
|
-
| --------- | -------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
23
|
-
| `plugin` | `string` | The Module Federation remote identifier in the format `remoteName/modulePath`.<br/>Example: `'myRemote/MyComponent'` |
|
|
24
|
-
|
|
25
|
-
### Returns
|
|
26
|
-
|
|
27
|
-
Returns a Vue async component that can be used in templates or rendered programmatically.
|
|
28
|
-
|
|
29
|
-
### Behavior
|
|
30
|
-
|
|
31
|
-
1. **Lazy loading:** The component is only loaded when it's actually rendered
|
|
32
|
-
2. **Error handling:** Throws an error if the remote module doesn't export a default component
|
|
33
|
-
3. **Type safety:** Expects the remote module to follow the `RemoteComponentModule` structure
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Usage Examples
|
|
38
|
-
|
|
39
|
-
### Basic Usage
|
|
40
|
-
|
|
41
|
-
```vue
|
|
42
|
-
<template>
|
|
43
|
-
<component :is="remoteComponent" />
|
|
44
|
-
</template>
|
|
45
|
-
|
|
46
|
-
<script setup lang="ts">
|
|
47
|
-
import { loadAsyncComponent } from '@linagora/linid-im-front-corelib';
|
|
48
|
-
|
|
49
|
-
const remoteComponent = loadAsyncComponent('myRemote/HeaderWidget');
|
|
50
|
-
</script>
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
### Dynamic Component Loading
|
|
56
|
-
|
|
57
|
-
```vue
|
|
58
|
-
<template>
|
|
59
|
-
<component
|
|
60
|
-
v-for="plugin in plugins"
|
|
61
|
-
:key="plugin"
|
|
62
|
-
:is="loadAsyncComponent(plugin)"
|
|
63
|
-
/>
|
|
64
|
-
</template>
|
|
65
|
-
|
|
66
|
-
<script setup lang="ts">
|
|
67
|
-
import { loadAsyncComponent } from '@linagora/linid-im-front-corelib';
|
|
68
|
-
|
|
69
|
-
const plugins = ['remote1/ComponentA', 'remote2/ComponentB'];
|
|
70
|
-
</script>
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
---
|
|
74
|
-
|
|
75
|
-
### In LinidZoneRenderer Context
|
|
76
|
-
|
|
77
|
-
The `loadAsyncComponent` function is used internally by `LinidZoneRenderer`:
|
|
78
|
-
|
|
79
|
-
```typescript
|
|
80
|
-
// Internal usage in LinidZoneRenderer
|
|
81
|
-
const components = entries.map((entry) => ({
|
|
82
|
-
...entry,
|
|
83
|
-
component: loadAsyncComponent(entry.plugin),
|
|
84
|
-
}));
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## Error Handling
|
|
90
|
-
|
|
91
|
-
### Module Not Found
|
|
92
|
-
|
|
93
|
-
If the remote module cannot be loaded:
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
const component = loadAsyncComponent('invalidRemote/Component');
|
|
97
|
-
// Throws: Error loading remote module
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### Missing Default Export
|
|
101
|
-
|
|
102
|
-
If the module doesn't export a default component:
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
// Remote module exports: export { MyComponent }
|
|
106
|
-
const component = loadAsyncComponent('myRemote/MyComponent');
|
|
107
|
-
// Throws: Failed to load component from myRemote/MyComponent
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**Solution:** Ensure your remote module exports a default component:
|
|
111
|
-
|
|
112
|
-
```vue
|
|
113
|
-
<!-- β
Correct - remote module (.vue file) -->
|
|
114
|
-
<template>
|
|
115
|
-
<div>My Component</div>
|
|
116
|
-
</template>
|
|
117
|
-
|
|
118
|
-
<script setup lang="ts">
|
|
119
|
-
// Default export automatic with <script setup>
|
|
120
|
-
// Nothing special to do!
|
|
121
|
-
</script>
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
**Alternative with Options API:**
|
|
125
|
-
|
|
126
|
-
```vue
|
|
127
|
-
<!-- β
Correct - remote module (.vue file) -->
|
|
128
|
-
<template>
|
|
129
|
-
<div>My Component</div>
|
|
130
|
-
</template>
|
|
131
|
-
|
|
132
|
-
<script lang="ts">
|
|
133
|
-
import { defineComponent } from 'vue';
|
|
134
|
-
|
|
135
|
-
export default defineComponent({
|
|
136
|
-
name: 'MyComponent',
|
|
137
|
-
// ...
|
|
138
|
-
});
|
|
139
|
-
</script>
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
**β Wrong - TypeScript/JavaScript file (not .vue):**
|
|
143
|
-
|
|
144
|
-
```typescript
|
|
145
|
-
// In a .ts file (not .vue)
|
|
146
|
-
// β Named export only - doesn't work with loadAsyncComponent
|
|
147
|
-
export const MyComponent = defineComponent({
|
|
148
|
-
// ...
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
// β
Correct - default export
|
|
152
|
-
export default defineComponent({
|
|
153
|
-
name: 'MyComponent',
|
|
154
|
-
// ...
|
|
155
|
-
});
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
## TypeScript Support
|
|
161
|
-
|
|
162
|
-
### Remote Module Structure
|
|
163
|
-
|
|
164
|
-
The function expects remotes to follow this structure:
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
/**
|
|
168
|
-
* Module structure for a Vue component exposed via Module Federation.
|
|
169
|
-
*/
|
|
170
|
-
interface RemoteComponentModule {
|
|
171
|
-
/**
|
|
172
|
-
* The default exported Vue component.
|
|
173
|
-
*/
|
|
174
|
-
default: Component;
|
|
175
|
-
}
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Type Inference
|
|
179
|
-
|
|
180
|
-
The returned component is fully typed as a Vue `Component`:
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
import type { Component } from 'vue';
|
|
184
|
-
|
|
185
|
-
const myComponent: Component = loadAsyncComponent('remote/Component');
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
---
|