|
1 | 1 | import { EditorContext } from "@/components/providers/editor-context-provider"; |
| 2 | +import { mfHost } from "@/components/providers/remote-module-provider"; |
2 | 3 | import { fetchAPI, getAPIUrl } from "@/lib/pulse-editor-website/backend"; |
3 | | -import { registerRemotes } from "@module-federation/runtime"; |
4 | | -import { useContext } from "react"; |
| 4 | +import { useCallback, useContext } from "react"; |
5 | 5 | import toast from "react-hot-toast"; |
6 | 6 | import { compare } from "semver"; |
7 | 7 | import { getRemote, getRemoteClientBaseURL } from "../module-federation/remote"; |
8 | 8 | import { |
9 | | - getRemoteLibVersion, |
10 | 9 | getHostMFVersion, |
| 10 | + getRemoteLibVersion, |
11 | 11 | getRemoteMFVersion, |
12 | 12 | } from "../module-federation/version"; |
13 | 13 | import { AppMetaData, ExtensionApp } from "../types"; |
14 | 14 |
|
15 | 15 | export default function useExtensionManager() { |
16 | 16 | const editorContext = useContext(EditorContext); |
17 | 17 |
|
18 | | - async function installExtension( |
19 | | - remoteOrigin: string, |
20 | | - id: string, |
21 | | - version: string, |
22 | | - ): Promise<void> { |
23 | | - const extension = await getExtensionInfoFromRemote( |
24 | | - remoteOrigin, |
25 | | - id, |
26 | | - version, |
27 | | - ); |
| 18 | + const installExtension = useCallback( |
| 19 | + async ( |
| 20 | + remoteOrigin: string, |
| 21 | + id: string, |
| 22 | + version: string, |
| 23 | + ): Promise<void> => { |
| 24 | + // Don't install if already installed |
| 25 | + if ( |
| 26 | + editorContext?.persistSettings?.extensions?.find( |
| 27 | + (ext) => |
| 28 | + ext.config.id === id && |
| 29 | + ext.config.version === version && |
| 30 | + ext.remoteOrigin === remoteOrigin, |
| 31 | + ) |
| 32 | + ) { |
| 33 | + console.log(`Extension ${id} is already installed`); |
| 34 | + return; |
| 35 | + } |
28 | 36 |
|
29 | | - console.log("Installing remote", extension); |
| 37 | + const extension = await getExtensionInfoFromRemote( |
| 38 | + remoteOrigin, |
| 39 | + id, |
| 40 | + version, |
| 41 | + ); |
30 | 42 |
|
31 | | - const remoteMFVersion = extension.mfVersion; |
| 43 | + console.log("Installing remote", extension); |
32 | 44 |
|
33 | | - const hostMFVersion = await getHostMFVersion(); |
| 45 | + const remoteMFVersion = extension.mfVersion; |
34 | 46 |
|
35 | | - if (!remoteMFVersion) { |
36 | | - throw new Error("Remote MF version is undefined"); |
37 | | - } else if (compare(remoteMFVersion, hostMFVersion) !== 0) { |
38 | | - throw new Error( |
39 | | - `Extension MF version ${remoteMFVersion} is not compatible with host MF version ${hostMFVersion}`, |
40 | | - ); |
41 | | - } |
| 47 | + const hostMFVersion = await getHostMFVersion(); |
42 | 48 |
|
43 | | - // TODO: Prevent CSS from being injected from the remote |
44 | | - // Register the frontend and backend from remote |
45 | | - registerRemotes( |
46 | | - getRemote( |
47 | | - extension.remoteOrigin, |
48 | | - extension.config.id, |
49 | | - extension.config.version, |
50 | | - ), |
51 | | - ); |
| 49 | + if (!remoteMFVersion) { |
| 50 | + throw new Error("Remote MF version is undefined"); |
| 51 | + } else if (compare(remoteMFVersion, hostMFVersion) !== 0) { |
| 52 | + throw new Error( |
| 53 | + `Extension MF version ${remoteMFVersion} is not compatible with host MF version ${hostMFVersion}`, |
| 54 | + ); |
| 55 | + } |
52 | 56 |
|
53 | | - const installedExtensions = |
54 | | - (await editorContext?.persistSettings?.extensions) ?? []; |
| 57 | + // TODO: Prevent CSS from being injected from the remote |
| 58 | + // Register the frontend and backend from remote |
| 59 | + mfHost.registerRemotes( |
| 60 | + getRemote( |
| 61 | + extension.remoteOrigin, |
| 62 | + extension.config.id, |
| 63 | + extension.config.version, |
| 64 | + ), |
| 65 | + ); |
55 | 66 |
|
56 | | - // Check if extension is already installed |
57 | | - if ( |
58 | | - installedExtensions.find((ext) => ext.config.id === extension.config.id) |
59 | | - ) { |
60 | | - return; |
61 | | - } |
| 67 | + const installedExtensions = |
| 68 | + (await editorContext?.persistSettings?.extensions) ?? []; |
62 | 69 |
|
63 | | - const updatedExtensions = [...installedExtensions, extension]; |
| 70 | + // Check if extension is already installed |
| 71 | + if ( |
| 72 | + installedExtensions.find((ext) => ext.config.id === extension.config.id) |
| 73 | + ) { |
| 74 | + return; |
| 75 | + } |
64 | 76 |
|
65 | | - editorContext?.setPersistSettings((prev) => { |
66 | | - return { |
67 | | - ...prev, |
68 | | - extensions: updatedExtensions, |
69 | | - }; |
70 | | - }); |
| 77 | + const updatedExtensions = [...installedExtensions, extension]; |
71 | 78 |
|
72 | | - // Try to set default extension for file types |
73 | | - tryAutoSetDefault(extension); |
74 | | - } |
| 79 | + editorContext?.setPersistSettings((prev) => { |
| 80 | + return { |
| 81 | + ...prev, |
| 82 | + extensions: updatedExtensions, |
| 83 | + }; |
| 84 | + }); |
| 85 | + |
| 86 | + // Try to set default extension for file types |
| 87 | + tryAutoSetDefault(extension); |
| 88 | + }, |
| 89 | + [editorContext?.persistSettings?.extensions], |
| 90 | + ); |
75 | 91 |
|
76 | 92 | async function uninstallExtension(name: string): Promise<void> { |
77 | 93 | const extensions = (await editorContext?.persistSettings?.extensions) ?? []; |
|
0 commit comments