-
Notifications
You must be signed in to change notification settings - Fork 6
Library Documentation
The syncmeta application consists of several widgets. Each of them has a specific purpose. The widgets are listed below
This is the main widget of the SyncMeta framework. It is used to create and edit models as well as metamodels.
Palette of elements that can be put on the canvas widget
Widget that gives awareness of activities of other users
Edit model attributes
Import/Export/Delete (meta-)models and guidance models. Download activity list as JSON
Import/Export/Delete viewpoint and views.
Export the design to JSON.
Export the design as ZIP (in the IMSLD format) or link the design to ILDE
One container to host them all. Contains the canvas widget, attribute widget, the palette widget, the activity widget and the debug widget.
Screenshot of the widget container:
For the local communication between the various widgets of the SyncMeta the new IWC library from the chair is used.
To initialize the IWC library, you have to call the static getInstance
function of the IWCWrapper
class. The getInstance
function takes the widget name as a parameter. The widget name has to be the same as the name of the widget in the config file. The getInstance
function returns an instance of the IWCWrapper
class.
Syncmeta widget names have to follow the naming convention: <name>-widget
. So the widget name for the canvas widget is canvas-widget
. This is necessary since the IWC library uses the widget name to determine the widget that should receive the message.
The IWCWrapper
class has the following functions:
-
sendLocalOTOperation
- sends an OT operation to the other widgets -
sendLocalNonOTOperation
- sends a non-OT operation to the other widgets -
registerOnDataReceivedCallback
- registers a callback function that is called when a message is received. The callback function takes theoperation
as a parameter. -
unregisterOnDataReceivedCallback
- unregisters the callback function that is called when a message is received.
There are several steps to create a new widget:
-
Choose a name for your widget. The name has to be unique. The name is used to identify the widget in the config file
-
Add the widget name to the config file under the
WIDGET.NAME
property. For the examples we assume that you named itExample
. The file should look like this:WIDGET: { NAME: { MAIN: "Canvas", PALETTE: "Palette", ATTRIBUTE: "Property Browser", ..., EXAMPLE: "Example", }, },
-
Create a new file in the /src/widgets/partials folder. You should name it
<widget-name>.widget.ts
, replace<widget-name>
with the name you chose in the first step. This file will contain the code of your widget. -
Define your widget. You can use the
customElement
decorator to register it in the registry. Use the getWidgetTagName to get the html tag name of the widget. Here is an example of theSAMPLE
widget:@customElement(getWidgetTagName(CONFIG.WIDGET.NAME.SAMPLE)) export class SampleWidget extends SyncMetaWidget( LitElement, getWidgetTagName(CONFIG.WIDGET.NAME.SAMPLE) ) {... }
-
Now it is time to configure YJS. In order to use yjs, we have to pass four properties onto our widget. Those are:
-
yjsHost
is the host of the y-websocket server. -
yjsPort
is the port of the y-websocket server. -
yjsProtocol
is the protocol of the y-websocket server. -
yjsSpaceTitle
is the title of the y-websocket space.
Here is our SAMPLE widget with the yjs configuration:
@customElement(getWidgetTagName(CONFIG.WIDGET.NAME.SAMPLE)) export class SampleWidget extends SyncMetaWidget( LitElement, getWidgetTagName(CONFIG.WIDGET.NAME.SAMPLE) ) { @property({ type: String }) yjsHost = "localhost"; @property({ type: Number }) yjsPort = 1234; @property({ type: String }) yjsProtocol = "ws"; @property({ type: String }) yjsSpaceTitle = window.spaceTitle; firstUpdated() { super.firstUpdated(); this.yjsInstance = getInstance({ host: this.yjsHost, port: this.yjsPort, protocol: this.yjsProtocol, spaceTitle: this.yjsSpaceTitle, }); const yDoc = await this.yjsInstance.connect() } }
For local development, you can let the defaults as they are. For production, you have to change them to match your y-websocket server. The
firstUpdated
function is called when the widget is first updated. This is the place where we initialize yjs. Note that getInstance function is not to be confused with the one fromIWCW
-
-
Now we can register the widget for the
IWCW
library. We do this by calling thegetInstance
function of theIWCW
library. Here is the example for our SAMPLE widget@customElement(getWidgetTagName(CONFIG.WIDGET.NAME.SAMPLE)) export class SampleWidget extends SyncMetaWidget( LitElement, getWidgetTagName(CONFIG.WIDGET.NAME.SAMPLE) ) { @property({ type: String }) yjsHost = "localhost"; @property({ type: Number }) yjsPort = 1234; @property({ type: String }) yjsProtocol = "ws"; @property({ type: String }) yjsSpaceTitle = window.spaceTitle; iwcw: IWCW; firstUpdated() { super.firstUpdated(); this.yjsInstance = getInstance({ host: this.yjsHost, port: this.yjsPort, protocol: this.yjsProtocol, spaceTitle: this.yjsSpaceTitle, }); const yDoc = await this.yjsInstance.connect() this.iwcw = IWCW.getInstance(CONFIG.WIDGET.NAME.SAMPLE); } render() { return html`<div>Sample Widget</div>`; } }
Now we can use our widget in our application