Skip to content
This repository has been archived by the owner on Nov 16, 2021. It is now read-only.

Design and implement imperative API export for Bento mode #36

Open
dvoytenko opened this issue Aug 31, 2020 · 2 comments
Open

Design and implement imperative API export for Bento mode #36

dvoytenko opened this issue Aug 31, 2020 · 2 comments

Comments

@dvoytenko
Copy link
Contributor

Currently the imperative Preact API (useImperativeHandle) is available to PreactBaseElement bridge (see ampproject/amphtml#30046). For instance, this is how PreactBaseElement subclasses implement on-actions.

However, this APIs also need to be exported in Bento mode so that developers can call these APIs on a DOM AMP element instance. E.g. a developer needs to be able to call:

<amp-video id="video1">...</amp-video>
...
<script>
  video1.pause();
</script>

Currently it's possible using CustomElement.enqueueAction API. However, this method has always been meant as an internal API and thus has serious issues with ergonomics.

In general the solution can be fairly straightforward simply proxying the Preact component's API on an element. However, some key nuances to be solved here are:

  1. APIs may need to be either namespaced or somehow we need to ensure non-collision with DOM APIs. E.g. we can either ensure that element.pause() is always ok, or we can call it element.ampPause() (poor ergonomics), or element.api.pause() or similar. The naming is subject to bikeshed of course.
  2. The Preact component's API is not available until the following sequence is executed: (a) AMP element is stubbed, (b) BaseElement is upgraded, (c) Preact component is rendered and its API is exported. This is quite a race condition and we need to think through how best to guide the developer API to avoid problems. For instance, element.api.pause() might work well because we can use element.api === undefined as an indication that the component/API are not ready yet.
  3. Related to upgrade race conditions, the enqueueAction implements action queueing. This is probably not a useful feature in Bento mode, but should be analyzed.
  4. We need to be careful with the fact that Preact component's imperative API handle can easily change given the Preact APIs. This means that we probably can't simply export the imperative handle directly, and should instead proxy it.
  5. Not yet clear if an element's API would map 1-to-1 to component's API. Proxying helps since it provides a layer to transform.
@samouri
Copy link
Member

samouri commented Aug 31, 2020

Related to upgrade race conditions, the enqueueAction implements action queueing. This is probably not a useful feature in Bento mode, but should be analyzed.

Another way to solve the race condition would be to queue up the api calls until upgrade has completed, then call them all.

@dvoytenko
Copy link
Contributor Author

Another way to solve the race condition would be to queue up the api calls until upgrade has completed, then call them all.

This is what we do in AMP mode. But I don't think we can do that in Bento. IMHO it should be up to the developer. For instance, an API call might be time-sensitive and would trigger a failure to play a video, or a failure to open a popup if timing is missed. And if that's what a developer wants, they can also do it themselves if we give them some sort of whenReady API. E.g. this is kind of like a queue, but by another name:

whenReady(element).then(() => element.api.play())

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants