diff --git a/tutormfe/hooks.py b/tutormfe/hooks.py index d88c7b44..931a75b1 100644 --- a/tutormfe/hooks.py +++ b/tutormfe/hooks.py @@ -15,3 +15,5 @@ MFE_APPS: Filter[dict[str, MFE_ATTRS_TYPE], []] = Filter() PLUGIN_SLOTS: Filter[list[tuple[str, str, str]], []] = Filter() + +INJECTED_SCRIPTS: Filter[list[tuple[str, str, str]], []] = Filter() \ No newline at end of file diff --git a/tutormfe/plugin.py b/tutormfe/plugin.py index 798f2c72..f1b265de 100644 --- a/tutormfe/plugin.py +++ b/tutormfe/plugin.py @@ -13,7 +13,7 @@ from tutor.types import Config, get_typed from .__about__ import __version__ -from .hooks import MFE_APPS, MFE_ATTRS_TYPE, PLUGIN_SLOTS +from .hooks import MFE_APPS, MFE_ATTRS_TYPE, PLUGIN_SLOTS, INJECTED_SCRIPTS # Handle version suffix in main mode, just like tutor core if __version_suffix__: @@ -138,6 +138,22 @@ def iter_plugin_slots(mfe_name: str) -> t.Iterable[tuple[str, str]]: """ yield from get_plugin_slots(mfe_name) +@tutor_hooks.lru_cache +def get_injected_scripts(mfe_name: str) -> list[tuple[str, str]]: + """ + This function is cached for performance. + """ + return [i[-2:] for i in INJECTED_SCRIPTS.iterate() if i[0] == mfe_name] + + +def iter_injected_scripts(mfe_name: str) -> t.Iterable[tuple[str, str]]: + """ + Yield: + + (script_name, script_content) + """ + yield from get_injected_scripts(mfe_name) + def is_mfe_enabled(mfe_name: str) -> bool: return mfe_name in get_mfes() @@ -155,6 +171,7 @@ def get_mfe(mfe_name: str) -> t.Union[MFE_ATTRS_TYPE, t.Any]: ("iter_plugin_slots", iter_plugin_slots), ("is_mfe_enabled", is_mfe_enabled), ("MFEMountData", MFEMountData), + ("iter_injected_scripts", iter_injected_scripts), ] ) diff --git a/tutormfe/templates/mfe/build/mfe/env.config.jsx b/tutormfe/templates/mfe/build/mfe/env.config.jsx index f2ed3c11..2044a967 100644 --- a/tutormfe/templates/mfe/build/mfe/env.config.jsx +++ b/tutormfe/templates/mfe/build/mfe/env.config.jsx @@ -15,9 +15,23 @@ function addPlugins(config, slot_name, plugins) { async function setConfig () { let config = { - pluginSlots: {} + pluginSlots: {}, + injectedScripts: [] }; + // Inject scripts here since FPF is not guaranteed to be present in all MFEs + {%- for script_name, script_content in iter_injected_scripts("all") %} + config.injectedScripts.push({{ script_content }}); + {%- endfor %} + + {%- for app_name, _ in iter_mfes() %} + if (process.env.APP_ID == '{{ app_name }}') { + {%- for script_name, script_content in iter_injected_scripts(app_name) %} + config.injectedScripts.push({{ script_content }}); + {%- endfor %} + } + {%- endfor %} + try { /* We can't assume FPF exists, as it's not declared as a dependency in all * MFEs, so we import it dynamically. In addition, for dynamic imports to