-
Notifications
You must be signed in to change notification settings - Fork 0
JS: making atoms come to life
JavaScript is the third and last layer provided by the atom library. This is where we add user interaction, provide enhanced UI functionalities and interface with remote services. But we can't do it willy-nilly! We must not forget that the browser is single-threaded, and that every time JavaScript runs, nothing else does. In other words, we need to be mindful and delegate as much of the work as possible to the platform. We approach the problem in two ways:
1- First, an atom is implicitly forbidden to do anything (i.e. run JS code) on its own. Instead, the JS delivered by the library must comply to a widget type providing lifecycle methods:
declare type Atom = { atomId: string
, start: (a: Atom) => Promise<void>
, stop: () => void
};The start method is where the action is. It will typically be the place where event listeners are registered and any other kind of initialisation kicks off. The platform will invoke it at a moment of its choosing, because only it knows exactly when the right time is.
The stop method is responsible for undoing everything that has been done during the lifetime of the atom. After executing that method, there should be no trace left of the atom in memory (except in the DOM): event listeners are unregistered, temporary resources are available for garbage collection.
2- Notably missing in the above is what happens during the lifetime of the atom. I'm glad you asked. The host platform, by delegating to the library, is taking a big risk: it is trivial to write a script that would clog the thread and bring the browser to a halt. Unfortunately it is very hard to enforce rules to prevent that, we just need to be mindful. However, we can offload a lot of the work to the platform itself in different areas.
The nice thing about that is we get some additional benefits out of it: the atom library doesn't know anything about the platform characteristics, but the platform itself does! Meaning, it can optimise for edge cases. An example would be that of network requests:
Readers may be accessing content while in the tube or somewhere there is no connection. The platform has the ability to detect whether that's the case and pool network calls until it is finally able to make them. The atom doesn't need to worry about that, it is only provided a nice interface such as
fetch(url, options): Promise<Response>.
With that in mind, we have established a contract between the platform and the atom library with interactivity in mind. The platform provides a set of services for which the implementation is platform-specific. The services are defined as an API which is passed to the atom at startup. Currently, the following services are available:
-
ophan. This service offers therecordAPI that is used to send ophan events. -
dom. This services is used to interact with the DOM viareadandwriteAPIs. -
viewport. This services is used to catch when the atom enters or leaves the viewport.