Thanks! The code is (almost) pure D3 and can be used independently of Observable. In that case you can safely ignore the {invalidation} parameter. You can also ignore {visibility}, but if you want to monitor it (to avoid drawing the maps when they're not on the screen), you'll have to replace {visibility} by something based on IntersectionObserver. I haven't tried but if you do please share :)
(The other specifics are quite easy to replace: they would be Promises.delay, and DOM.context2d.)
It does work in my browser, and from the spec it seems to be guaranteed to run *after* the returned zoom is applied to the target. In fact this another case where a zoom.on("init", callback) would be useful (like https://github.com/d3/d3-drag/issues/67 ): I could set up `target` and do the initial draw at that moment, based on who calls the zoom behaviour.