The public facing API SamePage exposes for other extensions.
Out of the box, SamePage extensions comes with just the Share Page
protocol. It exposes methods though for other extensions that developers could use to add other protocols to SamePage.
SamePage extensions attaches this API onto the window.samepage
object. This allows the methods to be global variables that other extensions could invoke to implement their protocols.
When trying to access the API from other extensions, you must be careful about race conditions. Unless you have some way to guarantee extension ordering on user's devices, your extension could load before the window.samepage
object has been set, leading to undefined
errors. To help with this, SamePage extensions dispatch a samepage:loaded
custom DOM event to the document.body
. Extensions could then listen for this event before accessing the API to safely ensure its availability.
The @samepage/external
NPM package is the team managed suite of utilities SamePage supports to help developers build SamePage
compatible extensions. It has a helper function that provides one such implementation for accessing the API, which you could view here. Below is an example of how to use it.
import getSamePageAPI from "@samepage/external/getSamePageAPI";
getSamePageAPI().then((api) => { // do stuff with `api`});
Below we outline the methods within the public API.
addNotebookListener
SamePage extensions will manage a web socket connection and handle messages from that connection automatically. Messages will typically be JSON
strings with an operation
field, which is used to route the message to the appropriate handler. External extensions could use addNotebookListener
to add more message handlers to that routing.
const { addNotebookListener } = api;
addNotebookListener({ operation: "EXAMPLE_PING"; // operation to listen for handler: ( data, // json object source, // notebook that sent the message uuid, // universal id of the message ) => { const { uuid, // uuid string workspace, // workspace name string app, // app id number } = source // do stuff with `data` }});
Note that this method will overwrite any existing handlers, including ones defined by SamePage extensions themselves. This is why it's typically good practice to define your operations with a prefix corresponding to the name of your extension, for example EXAMPLE_
.
removeNotebookListener
Removes any predefined listeners. This method is useful if you want to define messages in your protocol that should only be listened to a certain number of times before removing itself.
const { addNotebookListener, removeNotebookListener } = api;
addNotebookListener({ operation: "EXAMPLE_PING_ONCE"; handler: () => { console.log("ping!"); removeNotebookListener({ operation: "EXAMPLE_PING_ONCE", }) }});
sendToNotebook
Both of the methods above have to do with what to do when the notebook your extensions serves receives data. The sendToNotebook
helper is how you can send data to other notebooks. Note that you'll need the target Notebook's Universal Id in order to send it the data.
const { sendToNotebook } = api;
sendToNotebook({ // operation to send to another notebook operation: "EXAMPLE_PING", // Notebook Universal ID for the target notebook target: "abcd1234-abcd-1234-abcd-1234abcd1234", // JSON to send data: {}, })
Note that the following fields are needed for routing the message through SamePage's protocol and therefore should not be used in the data
field of this method:
app
workspace
operation
notebookUuid