We load the plugins that give wiki distinct capabilities only when a page calls for that function. As we strive to do everything at once we must distinguish a load in progress from plugins not yet and already successfully loaded.
Async Plugin Lifecycle shows an item from a page fetched from the federation and the plugin to interpret that item loaded on demand from an established location.
# Logic
This is the logic we use to allow many items of the same type to request a load simultaneously while only importing the requested plugin once. github
Blue steps handle the Plugin. This revolves around a 'Plugins' cache of already loaded plugins indexed by type.
Beige steps sequence requests. This revolves around a 'Queue' for waiting requests that exists only while a a request is in flight.
digraph { rankdir=LR node [shape=box style=filled] node [fillcolor=lightblue] 1; 3; 5; node [fillcolor=bisque] {rank=same; 1 -> 2 -> 3 -> 4 -> 5} "load type" -> 1 1 -> "have it" 2 -> "wait for it" 5 -> "got it" 2 -> 4 [style=dashed label="short\nlived\nqueue"] 1 [label="given Item of a Type\nif Type in Cache return it"] 2 [label="if Queue is present\nadd a Promise and return it\notherwise create empty Queue"] 3 [label="import Plugin for Type\nawait import completion\nadd Plugin to Cache"] 4 [label="for each Promise in Queue\nresolve Promise with Plugin\ndiscard the Queue"] 5 [label="return the Plugin"] }
These instructions return with an answer, a plugin or promise of a plugin, in three places. The caller must 'await' meaning it will be paused in all but the first case. Any computation depending on plugins will similarly expect awaits upstream.
See Frame Script Context in current use.