esm-integration
                                
                                 esm-integration copied to clipboard
                                
                                    esm-integration copied to clipboard
                            
                            
                            
                        Extending Wasm JS API with module namespace reflection
As far as I'm aware, when the original WebAssembly JS API was developed the ES module spec namespace exotic object had not been fully defined, thus exports was created as a plain JavaScript object, and treated as frozen for some defensibility.
As a result, when the ESM integration is complete, there are two JS objects that can be used to represent a Wasm module instance - this old frozen exports object (on top of which the ESM integration is currently specified), and the module namespace exotic object,
When module linking instantiates a Wasm module, it treats it as an "instance type", which is a type it can apply to any module instance - Wasm OR JS (//cc @lukewagner if I'm getting this correct).
But the representation in JS for this instance can either be a plain JS object or a module namespace depending on how the Wasm module was instantiated (ESM integration v JS API v Wasm module linking).
This leads to some questions:
- Should module linking expose all Wasm instances as namespace objects (I believe this is the current plan)
- If so, would that be done via a conversion when interfacing into JS only? Or would it be done eagerly?
- Should the WebAssembly JS API be extended to permit namespace exotic object construction for a given exportsobject? For example via amoduleInstance.getNamespace()or similar function?
- Alternatively, should the WebAssembly JS API update the .exportsintance property to be a JS module namespace exotic object? Since the object was defensively frozen, this should mostly be backwards compatible down to the null prototype differences -.hasOwnPropertychecks etc which may cause possible ecosystem issues.
It could be beneficial to start lining the specs up now along these lines to ensure there aren't any roadblocks when we get there.
I think it could be beneficial to have an explicit global module registry, similar to the custom elements registry. This notional code registry could also be used in conjunction with import maps. Such a system would have a lot of benefits , but specifically relating to wasm js imports , you could replace import “./thing.js” with ImportRegistry.get(“thing.js”).
From my many experiments, i think dlang has the best user experience for interop, see https://wiki.dlang.org/Generating_WebAssembly_with_LDC . But, even this could be improved by introducing a global registry. Also , import maps are great and this would make them even greater
Sorry I'm very late in responding to this, and thanks for writing this up. The issue of consistency with module namespace objects is interesting.
Should module linking expose all Wasm instances as namespace objects (I believe this is the current plan)
That makes sense as a possibility. Does this provide a better interface than having it exposed as WebAssembly.Instance objects? (which would have been my first guess)
Should the WebAssembly JS API be extended to permit namespace exotic object construction for a given exports object? For example via a moduleInstance.getNamespace() or similar function?
Are there any advantages, aside from consistency between the various interfaces, of exposing the exports as specifically a module namespace object?
I'm also curious if this should be something tackled in the ESM integration proposal, or as a smaller adjustment to the JS API (e.g., a moduleInstance.getNamespace() interface doesn't seem too tired to this proposal). There is an agenda item on the next CG meeting to discuss ESM integration (https://github.com/WebAssembly/meetings/blob/main/main/2022/CG-03-01.md) so I can mention this as a topic to potentially discuss as well.