Manifests are what are being loaded by TaleSpire first to be able to set a number of settings for the environment and know what to load. They are the only file that is required to be a specific name in a specific location, namely: manifest.json
in the folder for each Symbiote. For example that would be Symbiote_Location/Symbiotes/My_Symbiote_Name/manifest.json
(It's worth noting that the name of the folder the Symbiote is stored in doesn't need to be the same as the name of the Symbiote in the manifest, though using at least a similar name is advisable)
{ "manifestVersion": 1, "name": "mySymbioteName", "entryPoint": "/index.html"All the following fields are optional. For more info on optional see here"summary": "string", "descriptionFilePath": "string", "version": "1.0-alpha2 Electric Boogaloo", "license": "xyz", "about": { "website": "https://example.com", "authors": [ "Jane Doe", "John Doe" ] }, "api": { "version": "string", "initializeEarly": bool, "doNotUseNickname": bool, "initTimeout": 10, "subscriptions": { "category": { "eventSource": "myEventHandlerFunction" } }, "interop": { "id": } }, "controls": { "reload": bool, "navigation": bool }, "kind": "string", "icons": { "64x64": "string", "notification": "string" }, "environment": { "webViewBackgroundColor": "hexcode", "loadTargetBehavior": "string", "capabilities": [ "string" ], "extras": [ "string" ] } }
All local paths have to start with a forward slash "/" indicating the root directory of the Symbiote. Sub-directories are possible, but not going outside of the root of the Symbiote to load any files outside of it. For example my_index.html
and /../my_index.html
are not valid, while /my_index.html
and /sub_folder_name/my_index.html
are.
All URLs used in the manifest need to be complete, including a scheme and a fully qualified domain name. For example example.com
and www.example.com
are not valid URLs, https://example.com
on the other hand is valid.
While the vast majority of fields are optional, this does not mean they are unnecessary. To use certain features in your Symbiote those fields have to be specified; For example without a "version" defined in the "api" section, the Symbiotes API will not be injected. Similarly, without the interop ID specified no sync
messages can be sent via the API.
IDs throughout TaleSpire use the UUIDv4 standard. They are, when generated correctly, for all practical purposes guaranteed to be unique IDs without needing a centralized registration authority to make sure they are unique. This means that as long as a UUIDv4 generator is used that satisfies the specification you can be sure that your ID is unique. Our templated Symbiote creation already adds a newly generated UUIDv4 as interop ID for you, but you can also use whichever online UUID generator, local tool, etc you prefer.
Optional fields like summary, descriptionFilePath and version are a great way to communicate basic information to the users of your Symbiote. While a good and descriptive name can be enough to convey what a simple Symbiote does and how it works, a short extra summary can help clarify the included features. Similarly for more complex Symbiotes a description file (pointed to by descriptionFilePath) can contain tutorials, a getting started section, FAQs, a more thorough explanation of all included features and how to use them, ...
The Symbiote version is a free text field that does not enforce any type of versioning schema. If you want, you can use semantic versioning, cool version names, count backwards, the choice is yours. Pick something that you enjoy working with and that you feel gives your users the best understanding about the version of your Symbiote.
Events are organized into different categories and event sources. The event source is what a Symbiote subscribes to - the event itself gets delivered by the event source to the specified handler function. To give a practical example based on the onVisibilityEvent
event source from API version 0.1: symbiote
is the subscription "category", while onVisibilityEvent
is the "event source". This event source provides the two events hasBecomeVisible
and hasBecomeHidden
. If you subscribe to onVisibilityEvent
your event handler will receive all events from that source, but not from any other event sources. For example even though it's also part of the symbiote
category, you need to subscribe to onStateChangeEvent
separately if you want its events.
All events return their data in the following structure:
{ kind: <kind>, payload: <data> }Where "kind" is the actual event, for our example either
hasBecomeVisible
or hasBecomeHidden
, allowing the event handler to know which event it was that was triggered and "payload" is the actual data that is documented in the API.
Event handlers cannot be stored in a scoped variable like let foo = function() { ... }
, as that is not visible to the API invoking the handler and delivery of the event will fail.
You can define different icons for different sizes, however, right now the only size available is 64x64px. Icons must be PNG.
The notification icon is an exception to the other icons as it needs to be 24x24px in size and monochrome (but still has to be a PNG).
TaleSpire defaults the web view background color to white for compatibility with external websites, however this can lead to flickering when a Symbiote with dark background loads. With webViewBackgroundColor
you tell TaleSpire explicitly which color to use instead of white. Colors are set by using their hex code (including the hash #
) using either the 3 digit hex or 6 digit hex: #123
, #123456
. The body background color in your style sheets takes priority over this setting and will be visible over this once loaded.
Opening links or loading a page using window.open() can be set to open in a new browser tab using the _blank target. By default all pages that are loaded are loaded by the currently active tab (_blank
behaves as if it was _self
). With the loadTargetBehavior
field you can choose between different behaviors by setting it to one of the following strings:
none
: Opened links with target _blank
get suppressed and not loaded at all.currentTab
: Opened links with target _blank
get opened in the currently active tab instead (behaves like _self
). This is the default behavior.popup
: Opened links with target _blank
get opened in a popup.
The popup
behavior may be necessary in case websites need to open something in a different tab than the original one. This is the case for example to have a separate login page that uses third party authentication like Google login.
The capabilities array selects which capabilities a Symbiote has. The selection for each Symbiote should be as few as necessary for it to do what it is supposed to do. Possible capabilities are:
playAudio
: Only with this specified the Symbiote will be able to play audio.runInBackground
: With this specified the Symbiote will be able to run in the background, otherwise it will be shut down. Switching from one Symbiote to another counts as putting the previous Symbiote into the "background", just closing the side panel (without switching Symbiotes) does not.onStateChangeEvent
and listen for the willShutdown
event. However, do not rely on anything critical to be done at shutdown as this is a "best effort" event and we cannot guarantee this to be called in time, depending on the circumstances of when and why the shutdown occurs.{ "manifestVersion": 1, "name": "Website Viewer", "entryPoint": "https://example.com" }
This manifest loads the website "example.com" without injecting any of the TaleSpire API or doing anything else.
{ "manifestVersion": 1, "name": "Simple Local Symbiote", "entryPoint": "/local.html" }
This manifest loads the HTML file "local.html" from disk without injecting any of the TaleSpire API or doing anything else.
{ "manifestVersion": 1, "name": "Local Symbiote", "summary": "A cool summary", "entryPoint": "/my_index.html", "api": { "version": "0.1", "initTimeout": 10, "subscriptions": { "dice": { "onRollResults": "handleRollResult" }, "symbiote": { "onStateChangeEvent": "handleSymbioteStateChange" } } }, "environment": { "extras": [ "colorStyles" ] } }
This manifest loads the local HTML file "my_index.html", loads the API version 0.1 and calls the function "handleSymbioteStateChange" for various symbiote state changes, including the init event triggered once the API has initialized and communication with TaleSpire is set up.
The Symbiote is subscribed to all events from the "onRollResults" event source. The function "handleRollResult" will be called every time a rollResults event is triggered. Additionally, the colorStyles extra has been selected which injects a number of CSS color variables that provide the base colors of the TaleSpire theme to make it easier for the Symbiote to look at home in the TaleSpire UI.
{ "manifestVersion": 1, "name": "Super complex Symbiote", "summary": "This is a very complex and feature rich Symbiote", "descriptionFilePath": "/your_readme.md", "entryPoint": "/my_index.html", "api": { "version": "0.1", "initTimeout": 10, "doNotUseNickname": true, "subscriptions": { "dice": { "onRollResults": "handleRollResult" }, "symbiote": { "onStateChangeEvent": "handleSymbioteStateChange" }, "initiative": { "onInitiativeEvent": "handleInitiativeUpdate" }, "creatures": { "onCreatureStateChange": "handleCreatureUpdate" } } }, "controls": { "reload": true }, "icons": { "64x64": "/cool_icon.png", "notification": "/cool_notification_icon.png" }, "environment": { "capabilities": [ "playAudio", "runInBackground" ], "extras": [ "colorStyles" ] } }