Editor Integration
In this section you will learn how to embed the Fusebit Editor into your frontend web application.
For a detailed reference of the Fusebit Editor API, refer to the Editor API Reference.
Example Code
<div id="editor" style="width:800px;height:500px;"></div>
<script
src="https://cdn.fusebit.io/fusebit/js/fusebit-editor/latest/fusebit-editor.min.js"
type="text/javascript"
></script>
<script type="text/javascript">
// Load existing function or create one from template
fusebit
.createEditor(
document.getElementById('editor'),
'{boundaryId}',
'{functionId}',
{
accountId: '{accountId}',
subscriptionId: '{subscriptionId}',
baseUrl: 'https://api.{region}.fusebit.io',
accessToken: '{accessToken}',
},
{
template: {}, // IFunctionSpecification - function template if one does not exist yet
editor: {}, // IEditorOptions - control editor presentation and behavior
}
)
.then((editorContext) => {
// EditorContext
// ... subscribe to events etc.
})
.catch((err) => {
// ... display any errors
alert(err);
});
</script>
Conceptual Overview
The Fusebit Editor is a Javascript library that you can use to generate a UI component for editing a single Fusebit function. The Fusebit Editor communicates directly with the Fusebit HTTP API, allowing you to offer an authoring experience for Fusebit functions in your frontend application with a minimal amount of code.
Generally you will initialize the Fusebit Editor using the createEditor
method. You must specify the HTML element within which to create the editor, the function and boundary names, and the account details to use when communicating with the Fusebit HTTP API.
You can specify the account details as a static Javascript object that implements the IAccount
interface or you can dynamically resolve the account details by providing an AccountResolver
callback function. Use the IAccount
interface in cases when the access token is known ahead of time and does not need to be refreshed during the session. Use an AccountResolver
instance if you want to periodically refresh the access token and you want the editor to call back to the hosting application before every call to the Fusebit HTTP API.
By default, if the function identified by the boundary and function names does not exist yet, createEditor
will fail. You can optionally specify the template
property on the ICreateEditorOptions
object to provide a template that will be used to create a function if one does not already exist. This allows you to implement load-or-create semantics. You can also customize many aspects of the editor's presentation or behavior using the editor
property of the ICreateEditorOptions
object. For more details on configuring the editor, see below.
On success, createEditor
will return a promise that resolves to an EditorContext
instance. This allows you to subscribe to a variety of interesting Events
and perform simple operations on the editor.
Only a single instance of the editor on a given page is currently supported.
Including the Fusebit Library
The Fusebit library containing the editor is hosted on the CDN at the following location:
https://cdn.fusebit.io/fusebit/js/fusebit-editor/{major}/fusebit-editor.min.js
https://cdn.fusebit.io/fusebit/js/fusebit-editor/{major}/{minor}/fusebit-editor.min.js
https://cdn.fusebit.io/fusebit/js/fusebit-editor/{major}/{minor}/{patch}/fusebit-editor.min.js
https://cdn.fusebit.io/fusebit/js/fusebit-editor/latest/fusebit-editor.min.js
The library uses semver versioning, and you can decide what level of changes in the editor you want to receive automatically vs which you want to opt-in to. For example, using
https://cdn.fusebit.io/fusebit/js/fusebit-editor/1/0/fusebit-editor.min.js
will allow your application pick up all latest patch releases to version 1.0.x of the library, while using
https://cdn.fusebit.io/fusebit/js/fusebit-editor/1/fusebit-editor.min.js
will pin only the major version of the library and therefore allow your application to pick up all new non-breaking minor features and changes in the editor.
The URL with the latest
path segment will always point to the latest patch version available.
Accessing the Fusebit HTTP API
When you were on-boarded to the Fusebit platform, you should have been provided with a URL to the HTTP API instance running in the AWS region of your choice. Usually this will be the same region where your own application is hosted in AWS. In our documentation, we use https://api.{region}.fusebit.io as a stand-in for the HTTP API base URL, but you will need to replace it with the instance you are provided during onboarding, for example <https://api.us-east-1.fusebit.io >.
Authorization
The Fusebit Editor communicates directly with the Fusebit HTTP API to manage Fusebit functions. All calls to the Fusebit HTTP API must be authorized using an access token. Mechanisms to obtain a valid access token are documented in the authorization model section.
There are two ways of providing an access token to the Fusebit Editor.
Static Access Token
The Access token, along with accountId
, subcriptionId
and the baseUrl
of the Fusebit HTTP API can be directly provided to the Fusebit Editor using the IAccount
interface when calling the createEditor
method:
fusebit
.createEditor(document.getElementById('editor'), '{boundaryId}', '{functionId}', {
accountId: '{accountId}',
subscriptionId: '{subscriptionId}',
baseUrl: 'https://api.{region}.fusebit.io',
accessToken: '{accessToken}',
})
.then((editorContext) => {
// ...
});
The editor will use this access token for the duration of its lifetime. Since access tokens typically have expiry times associated with them, this mechanism is suitable only if the expected duration of the user's session with the editor does not exceed the expiry time.
Dynamic Access Token
An alternative to the static access token method, is to provide an AccountResolver
callback function to resolve the token. The Fusebit Editor will invoke this callback function before every call it makes to the Fusebit HTTP API. Since refreshing access tokens typically involves making HTTP API calls, it is important that the implementation of the callback supports in-memory caching of the access token for a duration adequate to its expiry time. A simplistic implementation might look like this:
let accountResolver = (currentAccount) => {
if (currentAccount && currentAccount.validUntil > Date.now()) {
// access token is still valid - return immediately
return Promise.resolve(currentAccount);
}
// refreshAccessToken is an application-specific way of obtaining the access token
return refreshAccessToken().then((newAccessToken) => {
return {
accountId: '{accountId}',
subscriptionId: '{subscriptionId}',
baseUrl: 'https://api.{region}.fusebit.io',
accessToken: newAccessToken,
validUntil: Date.now() + 60 * 60 * 1000, // valid for 1h
};
});
};
fusebit
.createEditor(document.getElementById('editor'), '{boundaryId}', '{functionId}', accountResolver)
.then((editorContext) => {
// ...
});
The dynamic access token method, while more involved, is also more robust than the static method. It allows the user to continue an uninterrupted session with the Fusebit Editor even if the access token expires and needs to be refreshed.
Configuring the Editor
The Fusebit editor is highly configurable. The template
property of the ICreateEditorOptions
object, which is passed to createEditor
, lets you specify a template for the function that the editor will create if the function does not exist already. That property is of type IFunctionSpecification
, and contains the following settings:
{
nodejs: { // Specify the files that comprise the function
files: {
'index.js': 'module.exports = (ctx, cb) => cb(null, { body: "hello" });',
'package.json': { dependencies: { async: '*' }},
}
},
configuration: { // Specify any Application Settings you want the editor to use
'MY_API_KEY': 'abc!123'
},
schedule: { // Configure scheduled execution
cron: '0 0 * * *',
timezone: 'US/Pacific'
},
metadata: { // Specify arbitrary metadata for the function, stored server-side
fusebit: { // Store metadata settings used by the Fusebit editor
runner : 'ctx => Superagent.get(ctx.url);',
}
}
}
The editor
property of the ICreateEditorOptions
object lets you configure the editor layout itself. The editor
property is of type IEditorOptions
, and contains the following settings:
{
theme: 'light', // Use light/dark built-in visual themes or custom themes
actionPanel: { // Configure the left-hand action panel
enableCodeOnlyToggle: true, // Display distraction-free coding toggle button
enableFullScreen: true, // Display full-screen button
},
logsPanel: { // Configure the bottom logs panel
maxSize: 10 * 1024, // Maximum number of characters that the logs panel shows
},
navigationPanel: { // Configure the left-hand navigation panel
hideCode: false, // Hide list of code files from the panel
hideFiles: [ 'middleware.js' ], // Hide select code files from the panel
hideConfigurationSettings: false, // Hide Application Settings from the panel
hideScheduleSettings: false, // Hide Scheduler Settings from the panel
hideRunnerTool: false // Hide Runner Settings from the panel
},
editorPanel: {}, // Currently unused
statusPanel: {}, // Currently unused
}
Styling the Editor
As mentioned in the previous section, the theme
property of IEditorOptions
allows the user to select between the built-in light
and dark
themes.
In certain cases, you may want to further customize the editor styling for a better fit with the rest of your application. To create a custom theme, you can use the built-in themes as a starting point, and modify them to your needs. You can find the theme CSS stylesheets for each version of the editor at the same CDN location where the editor is hosted, for example:
https://cdn.fusebit.io/fusebit/js/fusebit-editor/1/4/0/fusebit-light.css
https://cdn.fusebit.io/fusebit/js/fusebit-editor/1/4/0/fusebit-dark.css
To instantiate the editor with a custom theme:
- Create your own stylesheet based on the built-in themes, and make sure each rule selector starts with
.fusebit-theme-foo
, assumingfoo
is the name of your custom theme - Reference your stylesheet in the page where you are hosting the editor, either using an inline
<style>
block or by linking to it using a<link rel="stylesheet" type="text/css" href="fusebit-foo.css">
tag - When instantiating the editor set the
theme
property ofIEditorOptions
to your theme name, orfoo
in the above example.
When using custom themes, we recommend you pin the editor down to the patch version as described here. This ensures your application loads the exact version of the editor that you customized in your theme. Failing to do so may result in your application loading newer versions of the editor, which are not appropriately styled by your custom theme.
Handling Editor Dirty State
In certain scenarios, the hosting application may need to know whether the user has any unsaved changes in the editor. This is common if you are implementing functionality to close the editor or navigate away from it.
To detect unsaved changes (editor is in a "dirty state"), simply listen for
DirtyStateChangedEvent
as shown in the following snippet:
fusebit.createEditor(document.getElementById('editor'), '{boundaryId}', '{functionId}', {
// ...
}).then(editorContext => {
editorContext.on('dirty-state:changed', (event) => {
if(event.newState){
// Editor has unsaved changes
} else {
// All changes have been saved
}
});
Updated 19 days ago