Webinos Logo

AppState Synchronisation API

Webinos API Specifications

4 Sep 2012

Authors


Abstract

Interface to enable and manage application synchronisation.

Table of Contents

  1. Introduction
  2. Interfaces and Dictionaries
    1. Webinos
    2. SyncManager
    3. SyncObject
    4. SyncProperty
    5. SyncOptions
    6. SyncObjectStatus
  3. Callbacks
    1. SyncObjectSuccessCB
    2. PropertyChangedSuccessCB
    3. AppSyncErrorCB
  4. Enums
    1. AccessMode
    2. StateType
  5. Features
  6. Full WebIDL

Summary of Methods

Interface Method
Webinos
SyncManager void create(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, AppSyncErrorCB? errorCallback, SyncOptions? options)
void find(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, AppSyncErrorCB? errorCallback)
void detach(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, AppSyncErrorCB? errorCallback)
void remove(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, AppSyncErrorCB? errorCallback)
SyncObject void watch(DOMString propertyPath, PropertyChangedSuccessCB successCallback, AppSyncErrorCB? errorCallback)
void unwatch(DOMString propertyPath, PropertyChangedSuccessCB successCallback, AppSyncErrorCB? errorCallback)

Introduction

The interface provides a set of operations for the management of shared synchronised objects. It abstracts from the runtime application data exchange mechanisms and eases the development of distributed application, by reducing the complexity to simple read and write operations of object properties. The interface includes creation of and querying for objects in the JSON data exchange format and registration and deregistration for state changes.

Changes to objects created by this interface will be detected and synchronised among all participating peers automatically, e.g. setting properties or changing their values will affect all object copies. The synchronisation mode may be configured so that the participating peers may be distinct instances of the same application running on user's different devices (e.g. distributed cross-device application). In a further configuration an object may be synchroized across several different users and applications (e.g. cross-application chat or collaboration components).

The following example illustrates how a simple shopping-list component can be realized utilizing the AppState Synchronisation API. This component may be used by different applications and users while cooperatively operating on the same data.

Code example
//shared shopping data 
var sharedShopping = {
        listName:"After-work BBQ shopping list",
        itemsToBuy:[],
        itemsBought:[],
        totalSpent:0
};

//shopping list controller
//uses a 'uiHandler' function for user interface updates
var shoppingListController = {
        initializeList:function(){
                uiHandler("init-lists",sharedShopping);
        },
        addItemToList:function(itemName){
                sharedShopping.itemsToBuy.push(itemName);
        },
        moveItemToBoughtList:function(itemName,price){
                var itemIndex=sharedShopping.itemsToBuy.indexOf(itemName);
                if(itemIndex>-1){
                        var item = sharedShopping.itemsToBuy.slice(itemIndex,itemIndex+1);
                        if(item.length && item[0]===itemName){
                                sharedShopping.itemsBought.push(itemName);
                                sharedShopping.totalSpent+=price;
                        }
                }
                //synchronisation of shared object is invoked after object access
                //e.g. elements removed and added to arrays 
        },
        updateShoppingStatus:function(){
                uiHandler("mark-shopping-as",
                        (sharedShopping.itemsBought.length>0 && 
                        sharedShopping.itemsToBuy.length===0)?"complete":"incomplete");
                uiHandler("update-bought-items",sharedShoppingList.itemsBought);
                uiHandler("update-tobuy-items",sharedShoppingList.itemsToBuy);
        },
        updateTotalSpent:function(){
                uiHandler("set-total-spent",sharedShopping.totalSpent);
        }
};

//The functions shoppingListController.addItemToList(itemName) and shoppingListController.moveItemToBoughtList(itemName,price) 
//are used in user interface event handlers and/or the sharedShopping object
//is altered anywhere within the application.
//The following initializes the applications state synchronisation.

//success callback function that is called if an operation is completed successfully
var scb = function(syncObject){
        //update reference to synchronised object
        sharedShopping = syncObject.data;

        //add event handlers if necessary
        syncObject.onfail = function(){

        };

        //watch certain properties for changes
        syncObject.watch("itemsToBuy.length",shoppingListController.updateShoppingStatus);
        syncObject.watch("itemsBought.length",shoppingListController.updateShoppingStatus);
        shoppingListController.initializeList();
};

//error callback function that is called if an operation fails
var ecb = function(e){
        console.log('Error occured with name: '+e.name);
};

//specifies set up options for sync object creation that differ from defaults
var options = {
        //allow synchronisation across different applications
        crossAppSync:true,
        //allow synchronisation with other users
        crossUserSync:true,
        //remain state even if all participants get temporarily disconnected
        maintainTimeoutMinutes:120;
        //specify a reference object to be synchronised
        referenceObject:shoppingList;
};

//application state sync identifier
var syncSessionName = "after-work-bbq-shopping-list";

//searches for the shared and synchronised object that an other participant may have created already and joins this synchronisation session
webinos.sync.find(syncSessionName, scb,
 function(e){
        if(e.name==="NotFoundError"){
                //this app/user is the first participant, so create the sync object
                webinos.sync.create(syncSessionName,scb,ecb,options);
        }else{
                ecb(e);
        }
 }
); 


  

The AppState Synchronisation API is made available under the webinos namespace, i.e. webinos.sync.

Interfaces and Dictionaries

Interface Webinos (partial interface)

Creates the application state synchronisation namespace.

WebIDL
partial interface Webinos {
  readonly attribute SyncManager sync;
};

Access to public constants and functions are available via the namespace webinos.sync.

Attributes

readonly SyncManager sync

Partial interface that creates the webinos.sync namespace.

This attribute is readonly.

Interface SyncManager

Interface for management of the application state synchronisation. Covers three of the CRUD operations (create, read and delete) as an implicit object update is provided by the synchronisation mechanism if changes occur.

WebIDL
interface SyncManager {

  void create(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback, optional SyncOptions? options);

  void find(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

  void detach(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

  void remove(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback); 
};

Methods

create

Creates a synchronised object that may be used for application synchronisation.

Signature
void create(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback, optional SyncOptions? options);
Parameters
  • syncObjectIdentifier
    • Optional: No.
    • Nullable: No
    • Type: DOMString
    • Description: An identifier or name as a logical reference to the synchronised object.
  • successCallback
    • Optional: No.
    • Nullable: No
    • Type: SyncObjectSuccessCB
    • Description: The callback function to be called to notify the caller that the create operation was completed successfully,
  • errorCallback
    • Optional: Yes.
    • Nullable: Yes
    • Type: AppSyncErrorCB
    • Description: The callback function to be used to notify the caller that the create operation could not be completed successfully
  • options
    • Optional: Yes.
    • Nullable: Yes
    • Type: SyncOptions
    • Description: For the creation of a synchronised object options can be specified. If no options are specified then default values will be taken.
find

Finds a previously created synchronised object.

Signature
void find(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);
Parameters
  • syncObjectIdentifier
    • Optional: No.
    • Nullable: No
    • Type: DOMString
    • Description: An identifier, name or key as a logical reference to the synchronised object.
  • successCallback
    • Optional: No.
    • Nullable: No
    • Type: SyncObjectSuccessCB
    • Description: The callback function to be called to notify the caller that the find operation was completed successfully,
  • errorCallback
    • Optional: Yes.
    • Nullable: Yes
    • Type: AppSyncErrorCB
    • Description: The callback function to be used to notify the caller that the find operation could not be completed successfully
detach

Detach a previously created synchronised object from the synchronisation.

Signature
void detach(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

Permanently deactivates the synchronisation of a previously created synchronised object. Subsequent changes to the object will not be synchronised with remote peers and remote changes will not be reflected in local copy. The session will stay active as long as peers are attached to the session and the maintenance timeout has not exceeded.

Parameters
  • syncObjectIdentifier
    • Optional: No.
    • Nullable: No
    • Type: DOMString
    • Description: An identifier, name or key as a logical reference to the synchronised object.
  • successCallback
    • Optional: No.
    • Nullable: No
    • Type: SyncObjectSuccessCB
    • Description: The callback function to be called to notify the caller that the detach operation was completed successfully,
  • errorCallback
    • Optional: Yes.
    • Nullable: Yes
    • Type: AppSyncErrorCB
    • Description: The callback function to be used to notify the caller that the detach operation could not be completed successfully
remove

Removes a previously created synchronised object.

Signature
void remove(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

Permanently removes the synchronisation of a previously created synchronised object. Subsequent changes to the object will not be possible at any peer. Only the creator can remove an synchronised object.

Parameters
  • syncObjectIdentifier
    • Optional: No.
    • Nullable: No
    • Type: DOMString
    • Description: An identifier, name or key as a logical reference to the synchronised object.
  • successCallback
    • Optional: No.
    • Nullable: No
    • Type: SyncObjectSuccessCB
    • Description: The callback function to be called to notify the caller that the remove operation was completed successfully,
  • errorCallback
    • Optional: Yes.
    • Nullable: Yes
    • Type: AppSyncErrorCB
    • Description: The callback function to be used to notify the caller that the remove operation could not be completed successfully

Interface SyncObject

The SyncObject Interface to access the synchronised object, its metadata and event handlers.

WebIDL
[NoInterfaceObject]
interface SyncObject : EventTarget {

  attribute Object data;

  attribute SyncObjectStatus status;

  [TreatNonCallableAsNull] attribute EventHandler? onsync;

  [TreatNonCallableAsNull] attribute EventHandler? onfail;  

  [TreatNonCallableAsNull] attribute EventHandler? ondetach;

  [TreatNonCallableAsNull] attribute EventHandler? onremove;    

  void watch(DOMString propertyPath, PropertyChangedSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

  void unwatch(DOMString propertyPath, PropertyChangedSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

};

The SyncObject interface provides access to the object to be synchronised and its metadata as well as event handlers refering to the object.

Attributes

Object data

The root of the object to be synchronised.

Changes to properties of this object will be synchronised among all connected peers.

SyncObjectStatus status

Metadata about the object to be synchronised.

The status of the synchronised object may be accesses via properties of this object.

EventHandler? onsync

Event that fires when a synchronisation update occured.

A synchronisation message may contain multiple updates, for each update a separate event is fired. This concerns all type of updates.

EventHandler? onfail

Event that fires whenever a fatal error occurs.

In particular, the fired event notifies applications in case of a connection loss.

EventHandler? ondetach

Event that fires when the object has been detached from synchronisation.

EventHandler? onremove

Event that fires when the object has been removed by its creator.

Methods

watch

Watch a property, e.g. primitive attribute or sub-object, for changes.

Signature
void watch(DOMString propertyPath, PropertyChangedSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

If a change to a watched property is detected then all registered listeners are notified.

Parameters
  • propertyPath
    • Optional: No.
    • Nullable: No
    • Type: DOMString
    • Description: The path to the property of interest that should be watched, e.g. "subobject.counter".
  • successCallback
    • Optional: No.
    • Nullable: No
    • Type: PropertyChangedSuccessCB
    • Description: The callback to notify the caller that a change of the watched property or object occured.
  • errorCallback
    • Optional: Yes.
    • Nullable: Yes
    • Type: AppSyncErrorCB
    • Description: Function to be called if something goes wrong when trying to watch a property.
unwatch

Stop watching a property, e.g. primitive attribute or sub-object, for changes.

Signature
void unwatch(DOMString propertyPath, PropertyChangedSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

If a change to a watched property is detected then all registered listeners are notified.

Parameters
  • propertyPath
    • Optional: No.
    • Nullable: No
    • Type: DOMString
    • Description: The path to the property of interest that should not watched any longer.
  • successCallback
    • Optional: No.
    • Nullable: No
    • Type: PropertyChangedSuccessCB
    • Description: The callback that was used for the registration to notify the caller that a change of the watched property or object occured.
  • errorCallback
    • Optional: Yes.
    • Nullable: Yes
    • Type: AppSyncErrorCB
    • Description: Function to be called if something goes wrong when trying to unwatch a property.

Dictionary SyncProperty

The SyncProperty Interface

WebIDL
dictionary SyncProperty {

   DOMString propertyPath;

   Any? previousValue;

   Any? currentValue;
};

The SyncProperty interface provides information about the change of a watched property, containing its old and current

Dictionary Members

DOMString propertyPath

Path and name of the property refering to the update.

Any? previousValue

Holds a reference to a copy of the watched property before the last update.

Any? currentValue

Holds a reference to the watched property after the last update, its current state.

Dictionary SyncOptions

The SyncOptions Interface

WebIDL
dictionary SyncOptions {
   Boolean crossAppSync = false;

   Boolean crossUserSync = false;

   Long maintainTimeoutMinutes = 0;

   Object referenceObject = null;

   AccessMode accessMode = "rw";
};

For the creation of a sync object options may be specified.

Dictionary Members

Boolean crossAppSync

Specifies if the object should be synchronised across different applicaion.

If this property is set to true then the synchronisation mechanism will take care of sharing the state across different applications. The default value is false, thus limiting the synchronisation to peers using the same application.

Boolean crossUserSync

Specifies if the object should be synchronised across different users.

If this property is set to true then the synchronisation mechanism will take care of sharing the state across different personal zones. The default value is false, thus limiting the synchronisation to a single person only.

Long maintainTimeoutMinutes

Specifies if the synchronised object should be maintained for a certain amount of time (in minutes) if all peers get disconnected.

If this property is set to a value higher then 0 then the synchronisation mechanism will take care of maintaining the object in case of all peers gets disconnected. The default value is 0, thus the object will be garbage collected immediatelly if no peer is connected.

Object referenceObject

This object is used as a template to set up the initial state.

If this property is set then it will be taken as blueprint for the creation of the synchronisation object. The state of the reference object will be taken as initial state. If the reference object is not specified then an empty new synchronisation object will be created.

AccessMode accessMode

Specifies the access mode for the object and its properties.

Three access modes are distinguished to restrict access on objects. In the no-access mode ("na") only the creator may access the object, in read-only ("ro") mode only the creator may change the state of the synchronised object and a in full access ("rw") mode all peers may read and write the object. Default value is "rw".

Dictionary SyncObjectStatus

Interface to access the status refering a synchronised object.

WebIDL
dictionary SyncObjectStatus {

   SyncOptions options;

   StateType state;

   Date lastUpdate;

   Boolean isOwner;
};

Dictionary Members

SyncOptions options

The options that were used to create the synchronised object.

StateType state

The current state of the synchronised object.

Date lastUpdate

Time information about when the last synchronisation was performed.

Boolean isOwner

Flag indicating if ownership of the synchronised object.

Callbacks

SyncObjectSuccessCB

Callback function that is called if an operation on synchronisation is completed successfully.

WebIDL
callback SyncObjectSuccessCB = void (SyncObject syncObject);
Signature
void SyncObjectSuccessCB(SyncObject syncObject);
Parameters
  • syncObject
    • Optional: No.
    • Nullable: No
    • Type: SyncObject
    • Description: Holds the reference to the object to be synchronised as well as information about its status.

PropertyChangedSuccessCB

Callback function that is called if an change of a watched property occured.

WebIDL
callback PropertyChangedSuccessCB = void (SyncProperty syncProperty);
Signature
void PropertyChangedSuccessCB(SyncProperty syncProperty);
Parameters
  • syncProperty
    • Optional: No.
    • Nullable: No
    • Type: SyncProperty
    • Description: Holds information about the watched property.

AppSyncErrorCB

Callback function that is called if an operation could not be completed successfully.

WebIDL
callback AppSyncErrorCB = void (DOMError error);
Signature
void AppSyncErrorCB(DOMError error);
Parameters
  • error
    • Optional: No.
    • Nullable: No
    • Type: DOMError
    • Description: DOMError object detailing what went wrong; For example, the error name attribute may have one of the following values: NotFoundError if object or property cannot be found, InvalidModificationError if operation on the object or property cannot be done this way, TimeoutError if an operation could not be completed within the duration of one synchronisations round.

Enums

AccessMode

State type of a synchronised object.

WebIDL
enum AccessMode { "na", "ro", "rw" };

Values

na
ro
rw

StateType

State type of a shared object.

WebIDL
enum StateType { "initiated", "synchronised", "detached", "removed", "not_found" };

Values

initiated
synchronised
detached
removed
not_found

Features

This is the list of URIs used to declare this API's features, for use in the widget config.xml and as identifier for service type in service discovery functionality. For each URI, the list of functions covered is provided.

http://webinos.org/api/sync

Identifies the application state synchronisation service.

Full WebIDL

WebIDL
partial interface Webinos {
  readonly attribute SyncManager sync;
};

interface SyncManager {

  void create(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback, optional SyncOptions? options);

  void find(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

  void detach(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

  void remove(DOMString syncObjectIdentifier, SyncObjectSuccessCB successCallback, optional AppSyncErrorCB? errorCallback); 
}; 

callback SyncObjectSuccessCB = void (SyncObject syncObject);


[NoInterfaceObject]
interface SyncObject : EventTarget {

  attribute Object data;

  attribute SyncObjectStatus status;

  [TreatNonCallableAsNull] attribute EventHandler? onsync;

  [TreatNonCallableAsNull] attribute EventHandler? onfail;  

  [TreatNonCallableAsNull] attribute EventHandler? ondetach;

  [TreatNonCallableAsNull] attribute EventHandler? onremove;    

  void watch(DOMString propertyPath, PropertyChangedSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

  void unwatch(DOMString propertyPath, PropertyChangedSuccessCB successCallback, optional AppSyncErrorCB? errorCallback);

};

callback PropertyChangedSuccessCB = void (SyncProperty syncProperty);

callback AppSyncErrorCB = void (DOMError error);

dictionary SyncProperty {

   DOMString propertyPath;

   Any? previousValue;

   Any? currentValue;
}; 

dictionary SyncOptions {
   Boolean crossAppSync = false;

   Boolean crossUserSync = false;

   Long maintainTimeoutMinutes = 0;

   Object referenceObject = null;

   AccessMode accessMode = "rw";
};

enum AccessMode { "na", "ro", "rw" };


dictionary SyncObjectStatus {

   SyncOptions options;

   StateType state;

   Date lastUpdate;

   Boolean isOwner;
};

enum StateType { "initiated", "synchronised", "detached", "removed", "not_found" };