@@ -21,23 +21,23 @@ import { ToastAndroid } from "react-native";
2121import { copyFile , readDir , readFile , unlink , writeFile } from "react-native-fs" ;
2222import { devLog , errorLog , trace } from "../../utils/log" ;
2323import pluginMeta from "./meta" ;
24- import { ILazyProps , localFilePlugin , Plugin , PluginState } from "./plugin" ;
24+ import { localFilePlugin , Plugin , PluginState } from "./plugin" ;
2525import i18n from "../i18n" ;
2626import getOrCreateMMKV from "@/utils/getOrCreateMMKV" ;
2727import { safeParse } from "@/utils/jsonUtil" ;
2828import { IInjectable } from "@/types/infra" ;
2929import { IAppConfig } from "@/types/core/config" ;
30+ import delay from "@/utils/delay" ;
3031
3132const pluginsAtom = atom < Plugin [ ] > ( [ ] ) ;
32- const pluginStore = getOrCreateMMKV ( "plugin.cache" ) ;
33+ const pluginCacheStore = getOrCreateMMKV ( "plugin.cache" ) ;
3334
3435const ee = new EventEmitter < {
3536 "order-updated" : ( ) => void ;
3637 "enabled-updated" : ( pluginName : string , enabled : boolean ) => void ;
3738} > ( ) ;
3839
3940class PluginManager implements IPluginManager , IInjectable {
40-
4141 private appConfigService ! : IAppConfig ;
4242
4343 injectDependencies ( config : IAppConfig ) : void {
@@ -59,23 +59,32 @@ class PluginManager implements IPluginManager, IInjectable {
5959 private setPlugins ( plugins : Plugin [ ] ) {
6060 getDefaultStore ( ) . set ( pluginsAtom , plugins ) ;
6161
62- const cache : Record < string , ILazyProps > = { } ;
63- plugins . forEach ( it => {
64- if ( it . path ) {
65- cache [ it . path ] = {
66- name : it . name ,
67- hash : it . hash ,
68- path : it . path ,
69- instance : it . instance ,
70- supportedMethods : [ ...it . supportedMethods ] ,
71- } ;
62+ // 清理缓存中已卸载的插件
63+ const cachedKeys = pluginCacheStore . getAllKeys ( ) ;
64+ cachedKeys . forEach ( key => {
65+ if ( ! plugins . find ( it => it . path === key ) ) {
66+ pluginCacheStore . delete ( key ) ;
7267 }
7368 } ) ;
7469
75- pluginStore . set (
76- "plugins" ,
77- JSON . stringify ( cache ) ,
78- ) ;
70+ plugins . forEach ( it => {
71+ this . updatePluginCache ( it ) ;
72+ } ) ;
73+ }
74+
75+ private updatePluginCache ( plugin : Plugin ) {
76+ if ( plugin . path && plugin . state === PluginState . Mounted ) {
77+ pluginCacheStore . set (
78+ plugin . path ,
79+ JSON . stringify ( {
80+ name : plugin . name ,
81+ hash : plugin . hash ,
82+ path : plugin . path ,
83+ instance : plugin . instance ,
84+ supportedMethods : [ ...plugin . supportedMethods ] ,
85+ } ) ,
86+ ) ;
87+ }
7988 }
8089
8190 /**
@@ -90,8 +99,6 @@ class PluginManager implements IPluginManager, IInjectable {
9099 const pluginsFileItems = await readDir ( pathConst . pluginPath ) ;
91100 const allPlugins : Array < Plugin > = [ ] ;
92101
93- const cachePlugins = ( safeParse ( pluginStore . getString ( "plugins" ) ) ??
94- { } ) as Record < string , ILazyProps > ;
95102
96103 for ( let i = 0 ; i < pluginsFileItems . length ; ++ i ) {
97104 const pluginFileItem = pluginsFileItems [ i ] ;
@@ -104,12 +111,21 @@ class PluginManager implements IPluginManager, IInjectable {
104111 // 如果存在缓存信息
105112 let plugin : Plugin ;
106113 let isLazyLoad = false ;
107- if ( this . appConfigService . getConfig ( "basic.lazyLoadPlugin" ) && cachePlugins [ pluginFileItem . path ] ) {
108- const lazyProps = cachePlugins [ pluginFileItem . path ] ;
114+ if (
115+ this . appConfigService . getConfig (
116+ "basic.lazyLoadPlugin" ,
117+ ) &&
118+ pluginCacheStore . contains ( pluginFileItem . path )
119+ ) {
109120 isLazyLoad = true ;
121+ const lazyProps = safeParse ( pluginCacheStore . getString ( pluginFileItem . path ) ) ;
110122 lazyProps . loadFuncCode = async ( ) =>
111123 await readFile ( pluginFileItem . path , "utf8" ) ;
112- plugin = new Plugin ( null , pluginFileItem . path , lazyProps ) ;
124+ plugin = new Plugin (
125+ null ,
126+ pluginFileItem . path ,
127+ lazyProps ,
128+ ) ;
113129 } else {
114130 const funcCode = await readFile (
115131 pluginFileItem . path ,
@@ -125,12 +141,25 @@ class PluginManager implements IPluginManager, IInjectable {
125141 // 重复插件,直接忽略
126142 continue ;
127143 }
128- if ( ( plugin . state === PluginState . Mounted ) || isLazyLoad ) {
144+ if ( plugin . state === PluginState . Mounted || isLazyLoad ) {
129145 allPlugins . push ( plugin ) ;
130146 }
131147 }
132148 }
149+
133150 this . setPlugins ( allPlugins ) ;
151+ // 异步初始化插件
152+
153+ delay ( 10_000 , true ) . then ( async ( ) => {
154+ for ( let i = 0 ; i < allPlugins . length ; ++ i ) {
155+ const plugin = allPlugins [ i ] ;
156+
157+ if ( plugin . state === PluginState . Initializing ) {
158+ await plugin . ensureMounted ( ) ;
159+ this . updatePluginCache ( plugin ) ;
160+ }
161+ }
162+ } ) ;
134163 } catch ( e : any ) {
135164 ToastAndroid . show (
136165 `插件初始化失败:${ e ?. message ?? e } ` ,
@@ -352,7 +381,6 @@ class PluginManager implements IPluginManager, IInjectable {
352381 async uninstallPlugin ( hash : string ) {
353382 let plugins = [ ...this . getPlugins ( ) ] ;
354383 const targetIndex = plugins . findIndex ( _ => _ . hash === hash ) ;
355- console . log ( "卸载" , targetIndex ) ;
356384 if ( targetIndex !== - 1 ) {
357385 try {
358386 const pluginName = plugins [ targetIndex ] . name ;
@@ -508,7 +536,9 @@ class PluginManager implements IPluginManager, IInjectable {
508536 */
509537 getPluginsWithAbility ( ability : keyof IPlugin . IPluginInstanceMethods ) {
510538 return this . getPlugins ( ) . filter (
511- it => pluginMeta . isPluginEnabled ( it . name ) && it . supportedMethods . has ( ability ) ,
539+ it =>
540+ pluginMeta . isPluginEnabled ( it . name ) &&
541+ it . supportedMethods . has ( ability ) ,
512542 ) ;
513543 }
514544
0 commit comments