@@ -67,10 +67,140 @@ export const useAppStore = defineStore("app", () => {
6767 console . log ( `[AppStore] Imported ${ importedCount } stores` )
6868 }
6969
70+ const loadedExtensions = ref ( new Map ( ) )
71+ const extensionAPI = ref ( null )
72+
73+ function setExtensionAPI ( api ) {
74+ extensionAPI . value = api
75+ }
76+
77+ function getExtension ( path ) {
78+ return loadedExtensions . value . get ( path )
79+ }
80+
81+ async function loadExtension ( path , codeTransformer = null ) {
82+ try {
83+ if ( loadedExtensions . value . has ( path ) ) {
84+ console . warn ( `[AppStore] Extension already loaded from this path: ${ path } ` )
85+ throw new Error ( 'This extension file is already loaded' )
86+ }
87+
88+ if ( ! extensionAPI . value ) {
89+ throw new Error ( "Extension API not initialized" )
90+ }
91+
92+ let finalURL = path
93+
94+ if ( codeTransformer && path . startsWith ( 'blob:' ) ) {
95+ const response = await fetch ( path )
96+ const code = await response . text ( )
97+ const transformedCode = codeTransformer ( code )
98+
99+ const newBlob = new Blob ( [ transformedCode ] , { type : 'application/javascript' } )
100+ finalURL = URL . createObjectURL ( newBlob )
101+ }
102+
103+ const extensionModule = await import ( finalURL )
104+
105+ if ( finalURL !== path && finalURL . startsWith ( 'blob:' ) ) {
106+ URL . revokeObjectURL ( finalURL )
107+ }
108+
109+ const extensionName = extensionModule . metadata ?. name
110+ if ( extensionName ) {
111+ const alreadyLoaded = Array . from ( loadedExtensions . value . values ( ) ) . find (
112+ ext => ext . metadata ?. name === extensionName
113+ )
114+ if ( alreadyLoaded ) {
115+ console . warn ( `[AppStore] Extension "${ extensionName } " is already loaded` )
116+ throw new Error ( `Extension "${ extensionName } " is already loaded.` )
117+ }
118+ }
119+
120+ if ( typeof extensionModule . install === 'function' ) {
121+ await extensionModule . install ( extensionAPI . value , path )
122+
123+ const extensionData = {
124+ module : extensionModule ,
125+ path,
126+ loadedAt : new Date ( ) . toISOString ( ) ,
127+ metadata : extensionModule . metadata || { } ,
128+ enabled : true ,
129+ }
130+ loadedExtensions . value . set ( path , extensionData )
131+
132+ console . log ( `[AppStore] Extension loaded successfully: ${ path } ` )
133+
134+ return extensionModule
135+ } else {
136+ throw new Error ( 'Extension must export an install function' )
137+ }
138+ } catch ( error ) {
139+ console . error ( `[AppStore] Failed to load extension from ${ path } :` , error )
140+ throw error
141+ }
142+ }
143+
144+ function getLoadedExtensions ( ) {
145+ return Array . from ( loadedExtensions . value . values ( ) )
146+ }
147+
148+ function unloadExtension ( path ) {
149+ const extensionData = getExtension ( path )
150+ if ( ! extensionData ) return false
151+
152+ if ( extensionData . module && typeof extensionData . module . uninstall === 'function' ) {
153+ try {
154+ extensionData . module . uninstall ( extensionAPI . value , path )
155+ console . log ( `[AppStore] Extension uninstall called: ${ path } ` )
156+ } catch ( error ) {
157+ console . error ( `[AppStore] Error calling uninstall for ${ path } :` , error )
158+ }
159+ }
160+
161+ if ( extensionAPI . value && typeof extensionAPI . value . unregisterToolsByExtension === 'function' ) {
162+ extensionAPI . value . unregisterToolsByExtension ( path )
163+ }
164+
165+ loadedExtensions . value . delete ( path )
166+ console . log ( `[AppStore] Extension unloaded: ${ path } ` )
167+ return true
168+ }
169+
170+ function toggleExtension ( path ) {
171+ const extensionData = getExtension ( path )
172+ if ( ! extensionData ) return false
173+
174+ extensionData . enabled = ! extensionData . enabled
175+ console . log ( `[AppStore] Extension ${ extensionData . enabled ? 'enabled' : 'disabled' } : ${ path } ` )
176+ return extensionData . enabled
177+ }
178+
179+ function setExtensionEnabled ( path , enabled ) {
180+ const extensionData = getExtension ( path )
181+ if ( ! extensionData ) return false
182+
183+ extensionData . enabled = enabled
184+ console . log ( `[AppStore] Extension ${ enabled ? 'enabled' : 'disabled' } : ${ path } ` )
185+ return true
186+ }
187+
188+ function getExtensionEnabled ( path ) {
189+ return getExtension ( path ) ?. enabled ?? false
190+ }
191+
70192 return {
71193 stores,
72194 registerStore,
73195 exportStores,
74196 importStores,
197+ loadedExtensions,
198+ setExtensionAPI,
199+ loadExtension,
200+ getLoadedExtensions,
201+ unloadExtension,
202+ toggleExtension,
203+ setExtensionEnabled,
204+ getExtensionEnabled,
75205 }
76206} )
0 commit comments