88import {
99 configStore ,
1010 ExtensionRegistryOriginResolver ,
11- getMFImplementation ,
1211 localStorageAdapter ,
13- PostgrestExtensionStatePort ,
14- RegistryExtensionReleaseReader ,
15- setMFImplementation ,
1612 registerCoreResolvers ,
1713 TextResolver ,
1814 AudioResolver ,
@@ -26,10 +22,15 @@ import {
2622 PeerManager ,
2723 WebPeerRuntime ,
2824 JobManager ,
29- WebExtensionHost ,
30- type ExtensionStatePort ,
25+ type ExtensionModule ,
26+ type ExtensionSetupContribution ,
3127} from '@inkcre/core'
32- import { createInstance } from '@module-federation/enhanced/runtime'
28+ import { createInstance } from '@module-federation/runtime'
29+ import {
30+ ExtensionManager ,
31+ RegistryReleaseReader ,
32+ type WebExtensionModule ,
33+ } from '@inkcre/extension-runtime-client-web'
3334import * as InKCreCore from '@inkcre/core'
3435import * as Zod from 'zod'
3536import * as Vue from 'vue'
@@ -80,50 +81,53 @@ export function setupResolvers(): void {
8081// Configuration
8182// ============================================================================
8283
83- let extensionHost : WebExtensionHost | null = null
84+ type ClientExtensionModule = WebExtensionModule & ExtensionModule
85+ type ClientExtensionManager = ExtensionManager < ClientExtensionModule >
86+
87+ let extensionHost : ClientExtensionManager | null = null
8488let extensionHostStartup : Promise < void > | null = null
85- let extensionState : ExtensionStatePort | null = null
89+ let moduleFederation : ReturnType < typeof createInstance > | null = null
8690let webPeerRuntime : WebPeerRuntime | null = null
8791
88- export function initializeExtensionHost ( state : ExtensionStatePort ) : WebExtensionHost {
92+ export function initializeExtensionHost ( ) : ClientExtensionManager {
8993 extensionHostStartup = null
90- extensionState = state
9194 const registryOrigin = new ExtensionRegistryOriginResolver (
9295 ( ) => configStore . peerConfig . extension_registry_url
9396 )
94- extensionHost = new WebExtensionHost ( {
95- state,
96- releases : new RegistryExtensionReleaseReader ( ( ) => registryOrigin . resolve ( ) ) ,
97- moduleFederation : getMFImplementation ,
98- currentPeerId : ( ) => configStore . metaConfig . INKCRE_PEER_ID ,
99- hostSdkVersion : corePackageJson . version ,
97+ if ( ! moduleFederation ) throw new Error ( 'Module Federation has not been initialized.' )
98+ extensionHost = new ExtensionManager < ClientExtensionModule > ( {
99+ releases : new RegistryReleaseReader ( {
100+ registryOrigin : ( ) => registryOrigin . resolve ( ) ,
101+ hostSdk : { name : '@inkcre/core' , version : corePackageJson . version } ,
102+ } ) ,
103+ moduleFederation,
100104 } )
101105 return extensionHost
102106}
103107
104- export function getExtensionState ( ) : ExtensionStatePort {
105- if ( ! extensionState ) throw new Error ( 'Web Extension state port has not been initialized.' )
106- return extensionState
107- }
108-
109108/** Share one initial runtime restore across the app shell and management view. */
110109export function startExtensionHost ( ) : Promise < void > {
111110 if ( extensionHostStartup ) return extensionHostStartup
112- const startup = getExtensionHost ( ) . startup ( )
111+ const startup = getExtensionHost ( ) . startup ( configStore . metaConfig . INKCRE_PEER_ID )
113112 extensionHostStartup = startup . catch ( ( error : unknown ) => {
114113 extensionHostStartup = null
115114 throw error
116115 } )
117116 return extensionHostStartup
118117}
119118
120- export function getExtensionHost ( ) : WebExtensionHost {
119+ export function getExtensionHost ( ) : ClientExtensionManager {
121120 if ( ! extensionHost ) {
122121 throw new Error ( 'Web Extension Host state port has not been initialized.' )
123122 }
124123 return extensionHost
125124}
126125
126+ /** Project the running native module into the Client-owned setup popup contract. */
127+ export function getExtensionSetupContribution ( name : string ) : ExtensionSetupContribution | null {
128+ return getExtensionHost ( ) . getModule ( name ) ?. setup ?? null
129+ }
130+
127131/** Replace the browser-owned lease runtime after a validated Settings cutover. */
128132export function adoptWebPeerRuntime ( runtime : WebPeerRuntime ) : void {
129133 webPeerRuntime ?. stop ( )
@@ -154,10 +158,10 @@ export async function startConfiguredWebPeerRuntime(): Promise<void> {
154158
155159/**
156160 * Initialize Module Federation runtime.
157- * Creates the MF instance and injects it into core .
161+ * Creates the MF instance consumed by the application-owned Extension manager .
158162 */
159163export function initializeModuleFederation ( ) : void {
160- const mfInstance = createInstance ( {
164+ moduleFederation = createInstance ( {
161165 name : 'host' ,
162166 remotes : [ ] ,
163167 shared : {
@@ -212,21 +216,6 @@ export function initializeModuleFederation(): void {
212216 } ,
213217 } )
214218
215- // Inject MF implementation into core
216- const mfImpl = {
217- registerRemotes : (
218- remotes : Array < { name : string ; entry : string ; type ?: 'module' | 'script' } > ,
219- options ?: { force ?: boolean }
220- ) => {
221- mfInstance . registerRemotes ( remotes , options )
222- } ,
223- loadRemote : async < T > ( remoteName : string ) : Promise < T | null > => {
224- return mfInstance . loadRemote < T > ( remoteName )
225- } ,
226- }
227-
228- setMFImplementation ( mfImpl )
229-
230219 console . log ( '[Core] Module Federation initialized' )
231220}
232221
@@ -266,7 +255,7 @@ export async function initializeCore(options: { loadPeerConfig?: boolean } = {})
266255 JobManager . startWorker ( )
267256 setupResolvers ( )
268257 initializeModuleFederation ( )
269- initializeExtensionHost ( new PostgrestExtensionStatePort ( ) )
258+ initializeExtensionHost ( )
270259 if ( webPeerRuntime ) await webPeerRuntime . start ( )
271260 console . log ( '[Core] Initialization complete' )
272261}
0 commit comments