Skip to content

Commit 78cac8b

Browse files
committed
ref(extension): 切换至独立 Web Runtime
- 由 Client Web 组合 Registry、Module Federation 与 Extension manager - 通过已发布 tgz 接入 Runtime 0.1.0 并提升 Host SDK 至 0.1.2 - 适配精确 Peer 启停并保留 Twitter setup popup
1 parent 5c847d3 commit 78cac8b

26 files changed

Lines changed: 276 additions & 1942 deletions

‎apps/client-web/package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"@codemirror/state": "^6.5.2",
1919
"@codemirror/view": "^6.38.8",
2020
"@inkcre/core": "workspace:*",
21+
"@inkcre/extension-runtime-client-web": "https://github.com/InKCre/ext-reg/releases/download/runtime-client-web-v0.1.0/inkcre-extension-runtime-client-web-0.1.0.tgz",
2122
"@inkcre/ui-web": "1.4.0",
2223
"@module-federation/runtime": "^0.21.4",
2324
"@supabase/postgrest-js": "^2.84.0",

‎apps/client-web/src/components/extension/extensionCard/extensionCard.spec.ts‎

Lines changed: 0 additions & 113 deletions
This file was deleted.

‎apps/client-web/src/components/extension/extensionCard/extensionCard.vue‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import { ref, computed, nextTick, shallowRef, watch, type Component } from 'vue'
33
import { useI18n } from 'vue-i18n'
44
import { InkButton, InkSwitch, InkDialog, InkInput, InkJsonEditor } from '@inkcre/ui-web'
5-
import { getExtensionHost } from '@/core'
5+
import { getExtensionHost, getExtensionSetupContribution } from '@/core'
66
import { extensionCardProps, extensionCardEmits } from './extensionCard'
77
88
const props = defineProps(extensionCardProps)
@@ -14,7 +14,7 @@ const configPopupOpen = ref<boolean | Promise<boolean>>(false)
1414
const versionPopupOpen = ref<boolean | Promise<boolean>>(false)
1515
const setupPopupOpen = ref(false)
1616
const setupComponent = shallowRef<Component | null>(null)
17-
const setupContribution = shallowRef(getExtensionHost().getSetupContribution(props.extension.name))
17+
const setupContribution = shallowRef(getExtensionSetupContribution(props.extension.name))
1818
const togglePromise = ref<Promise<boolean> | null>(null)
1919
const isUninstalling = ref(false)
2020
const operationError = ref<string | null>(null)
@@ -51,7 +51,7 @@ const toggleModel = computed({
5151
operationError.value = error instanceof Error ? error.message : String(error)
5252
return props.enabled
5353
} finally {
54-
setupContribution.value = getExtensionHost().getSetupContribution(props.extension.name)
54+
setupContribution.value = getExtensionSetupContribution(props.extension.name)
5555
togglePromise.value = null
5656
}
5757
})()

‎apps/client-web/src/core.ts‎

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,7 @@
88
import {
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'
3334
import * as InKCreCore from '@inkcre/core'
3435
import * as Zod from 'zod'
3536
import * 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
8488
let extensionHostStartup: Promise<void> | null = null
85-
let extensionState: ExtensionStatePort | null = null
89+
let moduleFederation: ReturnType<typeof createInstance> | null = null
8690
let 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. */
110109
export 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. */
128132
export 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
*/
159163
export 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

Comments
 (0)