11/* eslint-disable no-await-in-loop */
22import { openDB } from 'idb'
33import * as React from 'react'
4+ import * as ReactDOM from 'react-dom'
45import * as valtio from 'valtio'
56import * as valtioUtils from 'valtio/utils'
67import { gt } from 'semver'
@@ -242,12 +243,13 @@ window.mcraft = {
242243 build : process . env . BUILD_VERSION ,
243244 ui : {
244245 registeredReactWrappers : { } ,
245- registerReactWrapper ( place : InjectUiPlace , component : React . FC ) {
246- window . mcraft . ui . registeredReactWrappers [ place ] ??= [ ]
247- window . mcraft . ui . registeredReactWrappers [ place ] . push ( component )
246+ registerReactWrapper ( place : InjectUiPlace , id : string , component : React . FC ) {
247+ window . mcraft . ui . registeredReactWrappers [ place ] ??= { }
248+ window . mcraft . ui . registeredReactWrappers [ place ] [ id ] = component
248249 } ,
249250 } ,
250251 React,
252+ ReactDOM,
251253 valtio : {
252254 ...valtio ,
253255 ...valtioUtils ,
@@ -361,23 +363,27 @@ const requestModsFromParentFrame = async (): Promise<ClientMod[]> => {
361363 } )
362364}
363365
364- const loadParentFrameModsIfRequested = async ( ) => {
366+ const loadParentFrameModsIfRequested = async ( ) : Promise < Set < string > > => {
367+ const activatedModNames = new Set < string > ( )
365368 try {
366369 const params = new URLSearchParams ( window . location . search )
367- if ( appQueryParams . parentFrameMods !== '1' && appQueryParams . parentFrameMods !== 'true' ) return
370+ if ( appQueryParams . parentFrameMods !== '1' && appQueryParams . parentFrameMods !== 'true' ) return activatedModNames
368371 if ( window . parent === window ) {
369372 console . warn ( 'mods=parent query param detected but no parent frame is available' )
370- return
373+ return activatedModNames
371374 }
372375
373376 const modsFromParent = await requestModsFromParentFrame ( )
374- if ( ! modsFromParent . length ) return
377+ if ( ! modsFromParent . length ) return activatedModNames
375378
376379 for ( const rawMod of modsFromParent ) {
377380 try {
378381 const normalizedMod = normalizeParentMod ( rawMod )
379382 await saveClientModData ( normalizedMod )
380- await activateMod ( normalizedMod , 'parent-frame' )
383+ const activated = await activateMod ( normalizedMod , 'parent-frame' )
384+ if ( activated ) {
385+ activatedModNames . add ( normalizedMod . name )
386+ }
381387 } catch ( err ) {
382388 const modName = rawMod ?. name ?? 'parent-frame-mod'
383389 modsErrors [ modName ] ??= [ ]
@@ -388,29 +394,35 @@ const loadParentFrameModsIfRequested = async () => {
388394 } catch ( err ) {
389395 console . error ( 'Error loading mods from parent frame' , err )
390396 }
397+ return activatedModNames
391398}
392399
393400export const appStartup = async ( ) => {
394401 void checkModsUpdates ( )
395- await loadParentFrameModsIfRequested ( )
402+ const parentFrameActivatedMods = await loadParentFrameModsIfRequested ( )
396403
397404 const mods = await getAllMods ( )
398405 const oldRegisteredReactWrappers = Object . entries ( window . mcraft ?. ui ?. registeredReactWrappers ) . reduce ( ( acc , [ place , components ] ) => acc + components . length , 0 )
399406 for ( const mod of mods ) {
407+ // Skip mods that were already activated from parent frame
408+ if ( parentFrameActivatedMods . has ( mod . name ) ) {
409+ continue
410+ }
400411 await activateMod ( mod , 'autostart' ) . catch ( e => {
401412 modsErrors [ mod . name ] ??= [ ]
402413 modsErrors [ mod . name ] . push ( `startup: ${ String ( e ) } ` )
403414 console . error ( `Error activating mod on startup ${ mod . name } :` , e )
404415 } )
405416 }
406- const newRegisteredReactWrappers = Object . entries ( window . mcraft ?. ui ?. registeredReactWrappers ) . reduce ( ( acc , [ place , components ] ) => acc + components . length , 0 )
407- hadReactUiRegistered . state = oldRegisteredReactWrappers !== newRegisteredReactWrappers
417+ hadReactUiRegistered . state = Object . keys ( window . mcraft ?. ui ?. registeredReactWrappers ) . length > 0
418+ hadModsActivated . state = true
408419}
409420
410421export const modsUpdateStatus = proxy ( { } as Record < string , [ string , string ] > )
411422export const modsWaitingReloadStatus = proxy ( { } as Record < string , boolean > )
412423export const modsErrors = proxy ( { } as Record < string , string [ ] > )
413424export const hadReactUiRegistered = proxy ( { state : false } )
425+ export const hadModsActivated = proxy ( { state : false } )
414426
415427const normalizeRepoUrl = ( url : string ) => {
416428 if ( url . startsWith ( 'https://' ) ) return url
0 commit comments