@linagora/linid-im-front-corelib 0.0.3 → 0.0.4
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/CHANGELOG.md +7 -0
- package/dist/core-lib.es.js +340 -345
- package/dist/core-lib.umd.js +1 -1
- package/dist/package.json +1 -1
- package/dist/types/src/lifecycle/skeleton.d.ts +6 -12
- package/dist/types/src/types/moduleLifecycle.d.ts +6 -12
- package/docs/module-lifecycle.md +44 -201
- package/package.json +1 -1
- package/src/lifecycle/skeleton.ts +7 -14
- package/src/types/moduleLifecycle.ts +6 -15
package/dist/core-lib.umd.js
CHANGED
|
@@ -9,4 +9,4 @@ ${h.slice(0,5).join(`
|
|
|
9
9
|
state: () => new MyClass()
|
|
10
10
|
Found in store "${O.$id}".`),w&&E&&h.hydrate&&h.hydrate(O.$state,w),$=!0,x=!0,O}function defineStore(t,s,h){let u;const d=typeof s=="function";u=d?h:s;function E(_,y){const R=vue.hasInjectionContext();if(_=(process.env.NODE_ENV==="test"&&activePinia&&activePinia._testing?null:_)||(R?vue.inject(piniaSymbol,null):null),_&&setActivePinia(_),process.env.NODE_ENV!=="production"&&!activePinia)throw new Error(`[🍍]: "getActivePinia()" was called but there was no active Pinia. Are you trying to use a store before calling "app.use(pinia)"?
|
|
11
11
|
See https://pinia.vuejs.org/core-concepts/outside-component-usage.html for help.
|
|
12
|
-
This will fail in production.`);_=activePinia,_._s.has(t)||(d?createSetupStore(t,s,u,_):createOptionsStore(t,u,_),process.env.NODE_ENV!=="production"&&(E._pinia=_));const $=_._s.get(t);if(process.env.NODE_ENV!=="production"&&y){const x="__hot:"+t,C=d?createSetupStore(x,s,u,_,!0):createOptionsStore(x,assign({},u),_,!0);y._hotUpdate(C),delete _.state.value[x],_._s.delete(x)}if(process.env.NODE_ENV!=="production"&&IS_CLIENT){const x=vue.getCurrentInstance();if(x&&x.proxy&&!y){const C=x.proxy,H="_pStores"in C?C._pStores:C._pStores={};H[t]=$}}return $}return E.$id=t,E}const useLinidZoneStore=defineStore("linidZoneStore",{state:()=>({zones:{}}),actions:{register(t,s){this.zones[t]||(this.zones[t]=[]),this.zones[t].push(s)}}}),_sfc_main=vue.defineComponent({__name:"LinidZoneRenderer",props:{zone:{}},setup(t){const s=t,h=useLinidZoneStore(),u=vue.ref([]),d=vue.ref(!1);return vue.watchEffect(()=>{d.value=!1;const E=h.zones[s.zone]||[];u.value=E.map(_=>({..._,component:loadAsyncComponent(_.plugin)})),Promise.resolve().then(()=>{d.value=!0})}),(E,_)=>(vue.openBlock(),vue.createElementBlock(vue.Fragment,null,[(vue.openBlock(!0),vue.createElementBlock(vue.Fragment,null,vue.renderList(u.value,(y,R)=>(vue.openBlock(),vue.createBlock(vue.resolveDynamicComponent(y.component),vue.mergeProps({key:y.plugin+R},{ref_for:!0},y.props),null,16))),128)),d.value&&u.value.length===0?vue.renderSlot(E.$slots,"default",{key:0},()=>[_[0]||(_[0]=vue.createElementVNode("div",null,"No components to render in this zone.",-1))]):vue.createCommentVNode("",!0)],64))}});var ModuleLifecyclePhase=(t=>(t.SETUP="setup",t.CONFIGURE="configure",t.INITIALIZE="initialize",t.READY="ready",t.POST_INIT="
|
|
12
|
+
This will fail in production.`);_=activePinia,_._s.has(t)||(d?createSetupStore(t,s,u,_):createOptionsStore(t,u,_),process.env.NODE_ENV!=="production"&&(E._pinia=_));const $=_._s.get(t);if(process.env.NODE_ENV!=="production"&&y){const x="__hot:"+t,C=d?createSetupStore(x,s,u,_,!0):createOptionsStore(x,assign({},u),_,!0);y._hotUpdate(C),delete _.state.value[x],_._s.delete(x)}if(process.env.NODE_ENV!=="production"&&IS_CLIENT){const x=vue.getCurrentInstance();if(x&&x.proxy&&!y){const C=x.proxy,H="_pStores"in C?C._pStores:C._pStores={};H[t]=$}}return $}return E.$id=t,E}const useLinidZoneStore=defineStore("linidZoneStore",{state:()=>({zones:{}}),actions:{register(t,s){this.zones[t]||(this.zones[t]=[]),this.zones[t].push(s)}}}),_sfc_main=vue.defineComponent({__name:"LinidZoneRenderer",props:{zone:{}},setup(t){const s=t,h=useLinidZoneStore(),u=vue.ref([]),d=vue.ref(!1);return vue.watchEffect(()=>{d.value=!1;const E=h.zones[s.zone]||[];u.value=E.map(_=>({..._,component:loadAsyncComponent(_.plugin)})),Promise.resolve().then(()=>{d.value=!0})}),(E,_)=>(vue.openBlock(),vue.createElementBlock(vue.Fragment,null,[(vue.openBlock(!0),vue.createElementBlock(vue.Fragment,null,vue.renderList(u.value,(y,R)=>(vue.openBlock(),vue.createBlock(vue.resolveDynamicComponent(y.component),vue.mergeProps({key:y.plugin+R},{ref_for:!0},y.props),null,16))),128)),d.value&&u.value.length===0?vue.renderSlot(E.$slots,"default",{key:0},()=>[_[0]||(_[0]=vue.createElementVNode("div",null,"No components to render in this zone.",-1))]):vue.createCommentVNode("",!0)],64))}});var ModuleLifecyclePhase=(t=>(t.SETUP="setup",t.CONFIGURE="configure",t.INITIALIZE="initialize",t.READY="ready",t.POST_INIT="postInit",t))(ModuleLifecyclePhase||{});class BasicRemoteModule{id;name;version;description;constructor(s,h,u,d){this.id=s,this.name=h,this.version=u,this.description=d}async setup(){return{success:!0}}async configure(s){return{success:!0}}async initialize(){return{success:!0}}async ready(){return{success:!0}}async postInit(){return{success:!0}}}exports.BasicRemoteModule=BasicRemoteModule,exports.LinidZoneRenderer=_sfc_main,exports.ModuleLifecyclePhase=ModuleLifecyclePhase,exports.useLinidZoneStore=useLinidZoneStore,Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"})}));
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linagora/linid-im-front-corelib",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Core library of the LinID Identity Manager project. Provides shared types, services, components, and utilities for front-end and plugin, enabling consistent integration across the LinID ecosystem.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/core-lib.umd.js",
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { App } from 'vue';
|
|
2
1
|
import type { ModuleHostConfig, RemoteModule } from '../types/module';
|
|
3
2
|
import type { ModuleLifecycleResult } from '../types/moduleLifecycle';
|
|
4
3
|
/**
|
|
@@ -44,10 +43,9 @@ export declare class BasicRemoteModule implements RemoteModule {
|
|
|
44
43
|
*
|
|
45
44
|
* Default implementation returns success.
|
|
46
45
|
* Override this method to add custom setup logic.
|
|
47
|
-
* @param _app - The Vue application instance.
|
|
48
46
|
* @returns Promise resolving to the lifecycle result.
|
|
49
47
|
*/
|
|
50
|
-
|
|
48
|
+
setup(): Promise<ModuleLifecycleResult>;
|
|
51
49
|
/**
|
|
52
50
|
* Configure phase - receive and validate host configuration.
|
|
53
51
|
*
|
|
@@ -56,11 +54,10 @@ export declare class BasicRemoteModule implements RemoteModule {
|
|
|
56
54
|
*
|
|
57
55
|
* Default implementation returns success.
|
|
58
56
|
* Override this method to add custom configuration logic.
|
|
59
|
-
* @param
|
|
60
|
-
* @param _config - Module-specific configuration from host.
|
|
57
|
+
* @param config - Module-specific configuration from host.
|
|
61
58
|
* @returns Promise resolving to the lifecycle result.
|
|
62
59
|
*/
|
|
63
|
-
|
|
60
|
+
configure(config: ModuleHostConfig): Promise<ModuleLifecycleResult>;
|
|
64
61
|
/**
|
|
65
62
|
* Initialize phase - register stores and initialize resources.
|
|
66
63
|
*
|
|
@@ -69,10 +66,9 @@ export declare class BasicRemoteModule implements RemoteModule {
|
|
|
69
66
|
*
|
|
70
67
|
* Default implementation returns success.
|
|
71
68
|
* Override this method to add custom initialization logic.
|
|
72
|
-
* @param _app - The Vue application instance.
|
|
73
69
|
* @returns Promise resolving to the lifecycle result.
|
|
74
70
|
*/
|
|
75
|
-
|
|
71
|
+
initialize(): Promise<ModuleLifecycleResult>;
|
|
76
72
|
/**
|
|
77
73
|
* Ready phase - signal that the module is ready for use.
|
|
78
74
|
*
|
|
@@ -81,10 +77,9 @@ export declare class BasicRemoteModule implements RemoteModule {
|
|
|
81
77
|
*
|
|
82
78
|
* Default implementation returns success.
|
|
83
79
|
* Override this method to add custom ready logic.
|
|
84
|
-
* @param _app - The Vue application instance.
|
|
85
80
|
* @returns Promise resolving to the lifecycle result.
|
|
86
81
|
*/
|
|
87
|
-
|
|
82
|
+
ready(): Promise<ModuleLifecycleResult>;
|
|
88
83
|
/**
|
|
89
84
|
* Post-initialization phase - cross-module integrations.
|
|
90
85
|
*
|
|
@@ -93,8 +88,7 @@ export declare class BasicRemoteModule implements RemoteModule {
|
|
|
93
88
|
*
|
|
94
89
|
* Default implementation returns success.
|
|
95
90
|
* Override this method to add custom post-init logic.
|
|
96
|
-
* @param _app - The Vue application instance.
|
|
97
91
|
* @returns Promise resolving to the lifecycle result.
|
|
98
92
|
*/
|
|
99
|
-
|
|
93
|
+
postInit(): Promise<ModuleLifecycleResult>;
|
|
100
94
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { App } from 'vue';
|
|
2
1
|
import type { ModuleHostConfig } from './module';
|
|
3
2
|
/**
|
|
4
3
|
* Module lifecycle phases enumeration.
|
|
@@ -36,7 +35,7 @@ export declare enum ModuleLifecyclePhase {
|
|
|
36
35
|
*
|
|
37
36
|
* Use this phase for cross-module integrations and final setup.
|
|
38
37
|
*/
|
|
39
|
-
POST_INIT = "
|
|
38
|
+
POST_INIT = "postInit"
|
|
40
39
|
}
|
|
41
40
|
/**
|
|
42
41
|
* Result of a lifecycle phase execution.
|
|
@@ -77,45 +76,40 @@ export interface ModuleLifecycleHooks {
|
|
|
77
76
|
*
|
|
78
77
|
* Use this to prepare the module for initialization and validate
|
|
79
78
|
* that all required dependencies are available.
|
|
80
|
-
* @param app - The Vue application instance.
|
|
81
79
|
* @returns Promise resolving to the lifecycle result.
|
|
82
80
|
*/
|
|
83
|
-
|
|
81
|
+
setup(): Promise<ModuleLifecycleResult>;
|
|
84
82
|
/**
|
|
85
83
|
* Called to configure the module with application-specific settings.
|
|
86
84
|
*
|
|
87
85
|
* Use this to receive and validate the host configuration for your module.
|
|
88
86
|
* This is where you should check that all required configuration is present.
|
|
89
|
-
* @param app - The Vue application instance.
|
|
90
87
|
* @param config - Module-specific configuration from host (from module-<name>.json).
|
|
91
88
|
* @returns Promise resolving to the lifecycle result.
|
|
92
89
|
*/
|
|
93
|
-
|
|
90
|
+
configure(config: ModuleHostConfig): Promise<ModuleLifecycleResult>;
|
|
94
91
|
/**
|
|
95
92
|
* Called to initialize the module's core functionality.
|
|
96
93
|
*
|
|
97
94
|
* Use this to register Pinia stores and initialize any resources
|
|
98
95
|
* your module needs to function.
|
|
99
|
-
* @param app - The Vue application instance.
|
|
100
96
|
* @returns Promise resolving to the lifecycle result.
|
|
101
97
|
*/
|
|
102
|
-
|
|
98
|
+
initialize(): Promise<ModuleLifecycleResult>;
|
|
103
99
|
/**
|
|
104
100
|
* Called when the module is ready to be used.
|
|
105
101
|
*
|
|
106
102
|
* Use this to perform final checks and emit ready state.
|
|
107
103
|
* At this point, all other modules have completed initialization.
|
|
108
|
-
* @param app - The Vue application instance.
|
|
109
104
|
* @returns Promise resolving to the lifecycle result.
|
|
110
105
|
*/
|
|
111
|
-
|
|
106
|
+
ready(): Promise<ModuleLifecycleResult>;
|
|
112
107
|
/**
|
|
113
108
|
* Called after all modules have been initialized.
|
|
114
109
|
*
|
|
115
110
|
* Use this for cross-module integrations and final setup that requires
|
|
116
111
|
* all modules to be ready.
|
|
117
|
-
* @param app - The Vue application instance.
|
|
118
112
|
* @returns Promise resolving to the lifecycle result.
|
|
119
113
|
*/
|
|
120
|
-
|
|
114
|
+
postInit(): Promise<ModuleLifecycleResult>;
|
|
121
115
|
}
|
package/docs/module-lifecycle.md
CHANGED
|
@@ -40,13 +40,13 @@ Each phase has a specific purpose and is executed for **all modules** before mov
|
|
|
40
40
|
**Hook signature:**
|
|
41
41
|
|
|
42
42
|
```typescript
|
|
43
|
-
async
|
|
43
|
+
async setup(): Promise<ModuleLifecycleResult>
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
**Implementation example:**
|
|
47
47
|
|
|
48
48
|
```typescript
|
|
49
|
-
async
|
|
49
|
+
async setup(): Promise<ModuleLifecycleResult> {
|
|
50
50
|
if (!app) {
|
|
51
51
|
return {
|
|
52
52
|
success: false,
|
|
@@ -75,14 +75,13 @@ async onSetup(app: App): Promise<ModuleLifecycleResult> {
|
|
|
75
75
|
**Hook signature:**
|
|
76
76
|
|
|
77
77
|
```typescript
|
|
78
|
-
async
|
|
78
|
+
async configure(config: ModuleHostConfig): Promise<ModuleLifecycleResult>
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
**Implementation example:**
|
|
82
82
|
|
|
83
83
|
```typescript
|
|
84
|
-
async
|
|
85
|
-
app: App,
|
|
84
|
+
async configure(
|
|
86
85
|
config: ModuleHostConfig
|
|
87
86
|
): Promise<ModuleLifecycleResult> {
|
|
88
87
|
if (!config.id) {
|
|
@@ -92,9 +91,6 @@ async onConfigure(
|
|
|
92
91
|
};
|
|
93
92
|
}
|
|
94
93
|
|
|
95
|
-
// Store configuration for later use
|
|
96
|
-
this.config = config;
|
|
97
|
-
|
|
98
94
|
return { success: true };
|
|
99
95
|
}
|
|
100
96
|
```
|
|
@@ -117,13 +113,13 @@ async onConfigure(
|
|
|
117
113
|
**Hook signature:**
|
|
118
114
|
|
|
119
115
|
```typescript
|
|
120
|
-
async
|
|
116
|
+
async initialize(): Promise<ModuleLifecycleResult>
|
|
121
117
|
```
|
|
122
118
|
|
|
123
119
|
**Implementation example:**
|
|
124
120
|
|
|
125
121
|
```typescript
|
|
126
|
-
async
|
|
122
|
+
async initialize(): Promise<ModuleLifecycleResult> {
|
|
127
123
|
// Register Pinia store
|
|
128
124
|
const pinia = app.config.globalProperties.$pinia;
|
|
129
125
|
pinia.use(myStorePlugin);
|
|
@@ -155,13 +151,13 @@ async onInitialize(app: App): Promise<ModuleLifecycleResult> {
|
|
|
155
151
|
**Hook signature:**
|
|
156
152
|
|
|
157
153
|
```typescript
|
|
158
|
-
async
|
|
154
|
+
async ready(): Promise<ModuleLifecycleResult>
|
|
159
155
|
```
|
|
160
156
|
|
|
161
157
|
**Implementation example:**
|
|
162
158
|
|
|
163
159
|
```typescript
|
|
164
|
-
async
|
|
160
|
+
async ready(): Promise<ModuleLifecycleResult> {
|
|
165
161
|
console.log(`Module ${this.name} v${this.version} is ready!`);
|
|
166
162
|
|
|
167
163
|
return {
|
|
@@ -188,13 +184,13 @@ async onReady(app: App): Promise<ModuleLifecycleResult> {
|
|
|
188
184
|
**Hook signature:**
|
|
189
185
|
|
|
190
186
|
```typescript
|
|
191
|
-
async
|
|
187
|
+
async postInit(): Promise<ModuleLifecycleResult>
|
|
192
188
|
```
|
|
193
189
|
|
|
194
190
|
**Implementation example:**
|
|
195
191
|
|
|
196
192
|
```typescript
|
|
197
|
-
async
|
|
193
|
+
async postInit(): Promise<ModuleLifecycleResult> {
|
|
198
194
|
// Access other modules from host's module registry
|
|
199
195
|
// Set up cross-module event listeners
|
|
200
196
|
// Perform integrations
|
|
@@ -205,29 +201,6 @@ async onPostInit(app: App): Promise<ModuleLifecycleResult> {
|
|
|
205
201
|
|
|
206
202
|
---
|
|
207
203
|
|
|
208
|
-
## Vue App Instance
|
|
209
|
-
|
|
210
|
-
All lifecycle hooks receive the Vue `app` instance as their first parameter:
|
|
211
|
-
|
|
212
|
-
```typescript
|
|
213
|
-
import type { App } from 'vue';
|
|
214
|
-
|
|
215
|
-
async onInitialize(app: App): Promise<ModuleLifecycleResult> {
|
|
216
|
-
// Access Pinia
|
|
217
|
-
const pinia = app.config.globalProperties.$pinia;
|
|
218
|
-
|
|
219
|
-
// Access router (when available)
|
|
220
|
-
const router = app.config.globalProperties.$router;
|
|
221
|
-
|
|
222
|
-
// Access other global properties
|
|
223
|
-
const i18n = app.config.globalProperties.$i18n;
|
|
224
|
-
|
|
225
|
-
return { success: true };
|
|
226
|
-
}
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
---
|
|
230
|
-
|
|
231
204
|
## Result Object
|
|
232
205
|
|
|
233
206
|
All lifecycle hooks must return a `ModuleLifecycleResult`:
|
|
@@ -298,9 +271,9 @@ class MyModule extends BasicRemoteModule {
|
|
|
298
271
|
}
|
|
299
272
|
|
|
300
273
|
// Override only the hooks you need
|
|
301
|
-
async
|
|
302
|
-
|
|
303
|
-
|
|
274
|
+
async initialize(): Promise<ModuleLifecycleResult> {
|
|
275
|
+
// do something
|
|
276
|
+
|
|
304
277
|
return { success: true };
|
|
305
278
|
}
|
|
306
279
|
}
|
|
@@ -336,13 +309,12 @@ class MyModule implements RemoteModule {
|
|
|
336
309
|
version = '1.0.0';
|
|
337
310
|
description = 'Description of what the module does';
|
|
338
311
|
|
|
339
|
-
async
|
|
312
|
+
async setup(): Promise<ModuleLifecycleResult> {
|
|
340
313
|
// Validate dependencies
|
|
341
314
|
return { success: true };
|
|
342
315
|
}
|
|
343
316
|
|
|
344
|
-
async
|
|
345
|
-
app: App,
|
|
317
|
+
async configure(
|
|
346
318
|
config: ModuleHostConfig
|
|
347
319
|
): Promise<ModuleLifecycleResult> {
|
|
348
320
|
// Apply configuration
|
|
@@ -352,19 +324,17 @@ class MyModule implements RemoteModule {
|
|
|
352
324
|
return { success: true };
|
|
353
325
|
}
|
|
354
326
|
|
|
355
|
-
async
|
|
356
|
-
//
|
|
357
|
-
const pinia = app.config.globalProperties.$pinia;
|
|
358
|
-
pinia.use(myStore);
|
|
327
|
+
async initialize(): Promise<ModuleLifecycleResult> {
|
|
328
|
+
// do something
|
|
359
329
|
return { success: true };
|
|
360
330
|
}
|
|
361
331
|
|
|
362
|
-
async
|
|
363
|
-
|
|
332
|
+
async ready(): Promise<ModuleLifecycleResult> {
|
|
333
|
+
// do something
|
|
364
334
|
return { success: true };
|
|
365
335
|
}
|
|
366
336
|
|
|
367
|
-
async
|
|
337
|
+
async postInit(): Promise<ModuleLifecycleResult> {
|
|
368
338
|
// Cross-module integrations
|
|
369
339
|
return { success: true };
|
|
370
340
|
}
|
|
@@ -415,9 +385,7 @@ Each phase should have a single, clear responsibility.
|
|
|
415
385
|
✅ **Good:**
|
|
416
386
|
|
|
417
387
|
```typescript
|
|
418
|
-
async
|
|
419
|
-
const pinia = app.config.globalProperties.$pinia;
|
|
420
|
-
pinia.use(myStore);
|
|
388
|
+
async initialize(): Promise<ModuleLifecycleResult> {
|
|
421
389
|
return { success: true };
|
|
422
390
|
}
|
|
423
391
|
```
|
|
@@ -425,11 +393,9 @@ async onInitialize(app: App): Promise<ModuleLifecycleResult> {
|
|
|
425
393
|
❌ **Bad:**
|
|
426
394
|
|
|
427
395
|
```typescript
|
|
428
|
-
async
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
await fetchUserData(); // Should be in onReady or onPostInit
|
|
432
|
-
integrateWithOtherModule(); // Should be in onPostInit
|
|
396
|
+
async initialize(): Promise<ModuleLifecycleResult> {
|
|
397
|
+
await fetchUserData(); // Should be in ready or postInit
|
|
398
|
+
integrateWithOtherModule(); // Should be in postInit
|
|
433
399
|
return { success: true };
|
|
434
400
|
}
|
|
435
401
|
```
|
|
@@ -485,7 +451,7 @@ return {
|
|
|
485
451
|
Validate prerequisites early in the Setup phase.
|
|
486
452
|
|
|
487
453
|
```typescript
|
|
488
|
-
async
|
|
454
|
+
async setup(): Promise<ModuleLifecycleResult> {
|
|
489
455
|
if (!window.someRequiredAPI) {
|
|
490
456
|
return {
|
|
491
457
|
success: false,
|
|
@@ -540,13 +506,11 @@ class SimpleModule extends BasicRemoteModule {
|
|
|
540
506
|
super('simple-module', 'Simple Module', '1.0.0');
|
|
541
507
|
}
|
|
542
508
|
|
|
543
|
-
async
|
|
544
|
-
const pinia = app.config.globalProperties.$pinia;
|
|
545
|
-
pinia.use(myStore);
|
|
509
|
+
async initialize(): Promise<ModuleLifecycleResult> {
|
|
546
510
|
return { success: true };
|
|
547
511
|
}
|
|
548
512
|
|
|
549
|
-
// No need for
|
|
513
|
+
// No need for setup, configure, ready, or postInit
|
|
550
514
|
}
|
|
551
515
|
|
|
552
516
|
export default new SimpleModule();
|
|
@@ -618,29 +582,29 @@ Host Application
|
|
|
618
582
|
│ └─ Load module via Module Federation (remoteName/lifecycle)
|
|
619
583
|
│
|
|
620
584
|
├─ 3. Phase 1: Setup (all modules in parallel)
|
|
621
|
-
│ ├─ module-A.
|
|
622
|
-
│ ├─ module-B.
|
|
623
|
-
│ └─ module-C.
|
|
585
|
+
│ ├─ module-A.setup(app)
|
|
586
|
+
│ ├─ module-B.setup(app)
|
|
587
|
+
│ └─ module-C.setup(app)
|
|
624
588
|
│
|
|
625
589
|
├─ 4. Phase 2: Configure (all modules in parallel)
|
|
626
|
-
│ ├─ module-A.
|
|
627
|
-
│ ├─ module-B.
|
|
628
|
-
│ └─ module-C.
|
|
590
|
+
│ ├─ module-A.configure(app, configA)
|
|
591
|
+
│ ├─ module-B.configure(app, configB)
|
|
592
|
+
│ └─ module-C.configure(app, configC)
|
|
629
593
|
│
|
|
630
594
|
├─ 5. Phase 3: Initialize (all modules in parallel)
|
|
631
|
-
│ ├─ module-A.
|
|
632
|
-
│ ├─ module-B.
|
|
633
|
-
│ └─ module-C.
|
|
595
|
+
│ ├─ module-A.initialize(app)
|
|
596
|
+
│ ├─ module-B.initialize(app)
|
|
597
|
+
│ └─ module-C.initialize(app)
|
|
634
598
|
│
|
|
635
599
|
├─ 6. Phase 4: Ready (all modules in parallel)
|
|
636
|
-
│ ├─ module-A.
|
|
637
|
-
│ ├─ module-B.
|
|
638
|
-
│ └─ module-C.
|
|
600
|
+
│ ├─ module-A.ready(app)
|
|
601
|
+
│ ├─ module-B.ready(app)
|
|
602
|
+
│ └─ module-C.ready(app)
|
|
639
603
|
│
|
|
640
604
|
└─ 7. Phase 5: Post-Init (all modules in parallel)
|
|
641
|
-
├─ module-A.
|
|
642
|
-
├─ module-B.
|
|
643
|
-
└─ module-C.
|
|
605
|
+
├─ module-A.postInit(app)
|
|
606
|
+
├─ module-B.postInit(app)
|
|
607
|
+
└─ module-C.postInit(app)
|
|
644
608
|
```
|
|
645
609
|
|
|
646
610
|
**Key points:**
|
|
@@ -685,12 +649,7 @@ The following features are planned for future versions:
|
|
|
685
649
|
Add direct router access for route registration:
|
|
686
650
|
|
|
687
651
|
```typescript
|
|
688
|
-
async
|
|
689
|
-
const router = app.config.globalProperties.$router;
|
|
690
|
-
router.addRoute({
|
|
691
|
-
path: '/my-module',
|
|
692
|
-
component: MyComponent
|
|
693
|
-
});
|
|
652
|
+
async initialize(): Promise<ModuleLifecycleResult> {
|
|
694
653
|
return { success: true };
|
|
695
654
|
}
|
|
696
655
|
```
|
|
@@ -748,7 +707,7 @@ Support for lazy-loaded module features that load on demand.
|
|
|
748
707
|
|
|
749
708
|
### Configuration Not Received
|
|
750
709
|
|
|
751
|
-
**Problem:** Module's `
|
|
710
|
+
**Problem:** Module's `configure` receives unexpected configuration
|
|
752
711
|
|
|
753
712
|
**Solutions:**
|
|
754
713
|
|
|
@@ -756,119 +715,3 @@ Support for lazy-loaded module features that load on demand.
|
|
|
756
715
|
2. Check the config file path: `module-<module-name>.json`
|
|
757
716
|
3. Validate JSON syntax in config file
|
|
758
717
|
4. Check browser network tab for config file fetch (404?)
|
|
759
|
-
|
|
760
|
-
---
|
|
761
|
-
|
|
762
|
-
## Examples
|
|
763
|
-
|
|
764
|
-
### Minimal Module
|
|
765
|
-
|
|
766
|
-
A module that only registers a store:
|
|
767
|
-
|
|
768
|
-
```typescript
|
|
769
|
-
import { BasicRemoteModule } from '@linagora/linid-im-front-corelib';
|
|
770
|
-
import type { ModuleLifecycleResult } from '@linagora/linid-im-front-corelib';
|
|
771
|
-
import type { App } from 'vue';
|
|
772
|
-
|
|
773
|
-
class MinimalModule extends BasicRemoteModule {
|
|
774
|
-
constructor() {
|
|
775
|
-
super('minimal-module', 'Minimal Module', '1.0.0');
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
async onInitialize(app: App): Promise<ModuleLifecycleResult> {
|
|
779
|
-
const pinia = app.config.globalProperties.$pinia;
|
|
780
|
-
pinia.use(myStore);
|
|
781
|
-
return { success: true };
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
|
|
785
|
-
export default new MinimalModule();
|
|
786
|
-
```
|
|
787
|
-
|
|
788
|
-
---
|
|
789
|
-
|
|
790
|
-
### Full Module with All Hooks
|
|
791
|
-
|
|
792
|
-
A complete module implementation:
|
|
793
|
-
|
|
794
|
-
```typescript
|
|
795
|
-
import { BasicRemoteModule } from '@linagora/linid-im-front-corelib';
|
|
796
|
-
import type {
|
|
797
|
-
ModuleLifecycleResult,
|
|
798
|
-
ModuleHostConfig,
|
|
799
|
-
} from '@linagora/linid-im-front-corelib';
|
|
800
|
-
import type { App } from 'vue';
|
|
801
|
-
|
|
802
|
-
class FullModule extends BasicRemoteModule {
|
|
803
|
-
private config: ModuleHostConfig | null = null;
|
|
804
|
-
|
|
805
|
-
constructor() {
|
|
806
|
-
super(
|
|
807
|
-
'full-module',
|
|
808
|
-
'Full Module',
|
|
809
|
-
'1.0.0',
|
|
810
|
-
'A complete module with all lifecycle hooks'
|
|
811
|
-
);
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
async onSetup(app: App): Promise<ModuleLifecycleResult> {
|
|
815
|
-
// Validate environment
|
|
816
|
-
if (!app) {
|
|
817
|
-
return {
|
|
818
|
-
success: false,
|
|
819
|
-
error: 'Vue app instance not available',
|
|
820
|
-
};
|
|
821
|
-
}
|
|
822
|
-
|
|
823
|
-
console.log('[Full Module] Setup phase');
|
|
824
|
-
return { success: true };
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
async onConfigure(
|
|
828
|
-
app: App,
|
|
829
|
-
config: ModuleHostConfig
|
|
830
|
-
): Promise<ModuleLifecycleResult> {
|
|
831
|
-
// Validate config
|
|
832
|
-
if (!config.id || config.id !== this.id) {
|
|
833
|
-
return {
|
|
834
|
-
success: false,
|
|
835
|
-
error: 'Invalid or missing module ID in configuration',
|
|
836
|
-
};
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
// Store config
|
|
840
|
-
this.config = config;
|
|
841
|
-
|
|
842
|
-
console.log('[Full Module] Configure phase', config);
|
|
843
|
-
return { success: true };
|
|
844
|
-
}
|
|
845
|
-
|
|
846
|
-
async onInitialize(app: App): Promise<ModuleLifecycleResult> {
|
|
847
|
-
// Register store
|
|
848
|
-
const pinia = app.config.globalProperties.$pinia;
|
|
849
|
-
pinia.use(myStore);
|
|
850
|
-
|
|
851
|
-
console.log('[Full Module] Initialize phase');
|
|
852
|
-
return {
|
|
853
|
-
success: true,
|
|
854
|
-
metadata: { storesRegistered: 1 },
|
|
855
|
-
};
|
|
856
|
-
}
|
|
857
|
-
|
|
858
|
-
async onReady(app: App): Promise<ModuleLifecycleResult> {
|
|
859
|
-
console.log('[Full Module] Ready phase - Module is now ready!');
|
|
860
|
-
return { success: true };
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
async onPostInit(app: App): Promise<ModuleLifecycleResult> {
|
|
864
|
-
console.log('[Full Module] Post-init phase - Setting up integrations');
|
|
865
|
-
return { success: true };
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
export default new FullModule();
|
|
870
|
-
```
|
|
871
|
-
|
|
872
|
-
Each phase has a specific purpose and is executed for **all modules** before moving to the next phase.
|
|
873
|
-
|
|
874
|
-
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linagora/linid-im-front-corelib",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Core library of the LinID Identity Manager project. Provides shared types, services, components, and utilities for front-end and plugin, enabling consistent integration across the LinID ecosystem.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/core-lib.umd.js",
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
* LinID Identity Manager software.
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import type { App } from 'vue';
|
|
28
27
|
import type { ModuleHostConfig, RemoteModule } from '../types/module';
|
|
29
28
|
import type { ModuleLifecycleResult } from '../types/moduleLifecycle';
|
|
30
29
|
|
|
@@ -81,10 +80,9 @@ export class BasicRemoteModule implements RemoteModule {
|
|
|
81
80
|
*
|
|
82
81
|
* Default implementation returns success.
|
|
83
82
|
* Override this method to add custom setup logic.
|
|
84
|
-
* @param _app - The Vue application instance.
|
|
85
83
|
* @returns Promise resolving to the lifecycle result.
|
|
86
84
|
*/
|
|
87
|
-
async
|
|
85
|
+
async setup(): Promise<ModuleLifecycleResult> {
|
|
88
86
|
return { success: true };
|
|
89
87
|
}
|
|
90
88
|
|
|
@@ -96,13 +94,11 @@ export class BasicRemoteModule implements RemoteModule {
|
|
|
96
94
|
*
|
|
97
95
|
* Default implementation returns success.
|
|
98
96
|
* Override this method to add custom configuration logic.
|
|
99
|
-
* @param
|
|
100
|
-
* @param _config - Module-specific configuration from host.
|
|
97
|
+
* @param config - Module-specific configuration from host.
|
|
101
98
|
* @returns Promise resolving to the lifecycle result.
|
|
102
99
|
*/
|
|
103
|
-
async
|
|
104
|
-
|
|
105
|
-
_config: ModuleHostConfig
|
|
100
|
+
async configure(
|
|
101
|
+
config: ModuleHostConfig /* eslint-disable-line @typescript-eslint/no-unused-vars */
|
|
106
102
|
): Promise<ModuleLifecycleResult> {
|
|
107
103
|
return { success: true };
|
|
108
104
|
}
|
|
@@ -115,10 +111,9 @@ export class BasicRemoteModule implements RemoteModule {
|
|
|
115
111
|
*
|
|
116
112
|
* Default implementation returns success.
|
|
117
113
|
* Override this method to add custom initialization logic.
|
|
118
|
-
* @param _app - The Vue application instance.
|
|
119
114
|
* @returns Promise resolving to the lifecycle result.
|
|
120
115
|
*/
|
|
121
|
-
async
|
|
116
|
+
async initialize(): Promise<ModuleLifecycleResult> {
|
|
122
117
|
return { success: true };
|
|
123
118
|
}
|
|
124
119
|
|
|
@@ -130,10 +125,9 @@ export class BasicRemoteModule implements RemoteModule {
|
|
|
130
125
|
*
|
|
131
126
|
* Default implementation returns success.
|
|
132
127
|
* Override this method to add custom ready logic.
|
|
133
|
-
* @param _app - The Vue application instance.
|
|
134
128
|
* @returns Promise resolving to the lifecycle result.
|
|
135
129
|
*/
|
|
136
|
-
async
|
|
130
|
+
async ready(): Promise<ModuleLifecycleResult> {
|
|
137
131
|
return { success: true };
|
|
138
132
|
}
|
|
139
133
|
|
|
@@ -145,10 +139,9 @@ export class BasicRemoteModule implements RemoteModule {
|
|
|
145
139
|
*
|
|
146
140
|
* Default implementation returns success.
|
|
147
141
|
* Override this method to add custom post-init logic.
|
|
148
|
-
* @param _app - The Vue application instance.
|
|
149
142
|
* @returns Promise resolving to the lifecycle result.
|
|
150
143
|
*/
|
|
151
|
-
async
|
|
144
|
+
async postInit(): Promise<ModuleLifecycleResult> {
|
|
152
145
|
return { success: true };
|
|
153
146
|
}
|
|
154
147
|
}
|