Question for champions: Share or detach host from guest compartment by default?
#50 is not ready to land because it fails to adequately account for the case where a guest compartment needs a fresh static record memo (so it can reload) and also reuse the host’s loader’s load hooks. (I’ve made the mistake of conflating the effects of loadHook and memo sharing.) The options need to be orthogonal and the design directions come in two flavors.
(Please weigh in for ❤️ or 🚀 above, or provide feedback in free form.)
❤️: Share by default (which I suspect to be more common) 🚀: Detach by default (which is generally safer)
- Adopt, override, or omit
resolveHook- ❤️ (share by default, explicit detach)
- adopt:
-
new Compartment()
-
- override:
-
new Compartment({ resolveHook })
-
- omit:
-
new Compartment({ resolveHook: null })
-
- adopt:
- 🚀 (detach by default, explicit share)
- adopt:
-
new Compartment({ shareResolveHook: true })
-
- override:
-
new Compartment({ resolveHook })
-
- omit:
-
new Compartment()
-
- adopt:
- ❤️ (share by default, explicit detach)
- Adopt, override, or omit loadHook
- ❤️ (share by default, explicit detach)
- adopt:
-
new Compartment()
-
- override:
-
new Compartment({ loadHook })
-
- omit:
-
new Compartment({ loadHook: null })
-
- adopt:
- 🚀 (detach by default, explicit share)
- adopt:
-
new Compartment({ shareLoadHook: true })
-
- override:
-
new Compartment({ loadHook })
-
- omit:
-
new Compartment()
-
- adopt:
- ❤️ (share by default, explicit detach)
- Adopt or detach static module record memo
- ❤️ (share by default, explicit detach)
- adopt:
-
new Compartment()
-
- detach:
-
new Compartment({ detach: true })
-
- adopt:
- 🚀 (detach by default, explicit share)
- adopt:
-
new Compartment({ shareRecords: true })
-
- detach:
-
new Compartment()
-
- adopt:
- ❤️ (share by default, explicit detach)
- Adopt host globals or create new globals
- ❤️ (share by default, detach implied by
globalsoption)- adopt:
-
new Compartment()
-
- detach:
-
new Compartment({ globals: {} })
-
- adopt:
- or ❤️ (share by default, explicit detach required)
- adopt:
-
new Compartment()
-
- detach:
-
new Compartment({ detachGlobals: true }) -
new Compartment({ detachGlobals: true, globals: {x, y z} })
-
- adopt:
- 🚀 (detach by default, explicit share)
- adopt:
-
new Compartment({ shareGlobal: true })
-
- detach:
-
new Compartment() -
new Compartment({ globals: {} }) -
new Compartment({ globals: {x, y z} })
-
- adopt:
- ❤️ (share by default, detach implied by
I think I would like to convince this group that option B is generally better, even though detached global by default will be surprising the to majority of users. On the other hand, I suspect that attaching the static module record by default will also have surprising negative effects. We could pursue a hybrid, but I know that my mind at least has a hobgoblin.
Please let me know what you think and I’ll update this change to reflect the general favor of the champion group.
Today in the first TC39 Module Harmony call, @littledan expressed a preference for guest compartments to generally default to sharing loader behaviors with the host compartment. This interacts with import maps, if the host-defined loader uses one: If a guest compartment falls through to the host’s load hook from the host-defined compartment/loader (the initial realm’s loader), I take that to mean that the guest would benefit from the host’s import map. (cc @syg)
To further enumerate some of the scenarios:
- If setting a
resolveHookbut not aloadHook, would the resolution default to host module resolution? - If setting a
loadHookbut not aresolveHook, would the host resolution still apply anyway, since these hooks are entirely indepenent? - Even if setting a
resolveHook, it can still be useful to have access to the host resolver. I previously proposed a second argument toimport.meta.resolveto make allimport.meta.resolveinstances generic resolvers. I think this would be useful to enable calling out to the host loader - If we did get the ability to "call out" to the host loader via a generic
import.meta.resolveor otherwise, do we even need the host resolver by default, when it might be as simple asresolveHook: hostResolver? When a clean slate compartment should be the use case prioritised.