-
Notifications
You must be signed in to change notification settings - Fork 23
Contact Service Connector Interface Proposal Draft
Designing an interface before you have consumers isn't easy, and I've almost certainly overlooked things or gotten a few things wrong. But I think it's better to go in with a small kernel of a plan.
Anyhow, this is my disclaimer that these interfaces might change over time. But it's a start.
Asynchronous functions should return a Promise, using toolkit's Promises library.
To be implemented in order to connect to contact providers. Some of this will be boilerplace that can likely be implemented in a base class for subclassing.
class {
/**
* Constructor
* Called by the Connector Manager when its time to create a new instance of this class.
* Unless you're testing, you probably shouldn't be instantiating one of these on your own -
* you should let the Connector Manager take care of that.
*
* @param aAccountKey the unique accountKey assigned to this instance. Maps to the preferences
* branch being used to store preferences.
* @param aListener the object that should be called when items are imported, added, removed, or
* changed in this contact service.
* @param aCache a simple storage object that can be used to store a snap-shot of the contact
* service's records. This is useful in order to determine if a contact has changed,
* is new, or has been removed. This value is not passed if isSyncable is false.
*/
(constructor): function(aAccountKey, aListener, aCache [optional]);
/** Read-only attributes **/
/**
* Returns the unique accountKey passed into the constructor.
*/
get accountKey;
/**
* Returns whether or not we should be reading in changes from this contact provider.
*/
get isSyncable;
/**
* Returns whether or not we're able to write changes to this contact provider.
*/
get isWritable;
/**
* Returns whether or not we need to poll the contact provider for changes, or if we can
* expect the contact provider to push them on their own.
*/
get shouldPoll;
/**
* Returns the human-readable and user-set name for this connection. Alias for the
* displayName preference.
*/
get displayName;
/** Writable attributes **/
/**
* Returns the JSON object representing the preferences for this Connector.
*/
get prefs();
/**
* Writes a JSON object to the preferences for this Connector.
*
* @param aJSONObj the JSON object to write.
*/
set prefs(aJSONObj);
/**
* Returns true if the init function of this conncetor has finished its job.
*/
get initialized();
/**
* Returns true if the init function of this connector is in the process of finishing its job.
*/
get initializing();
/** Instance functions **/
/**
* Asynchronous function that tests that we can successfully connect to the
* contact provider.
*
* @returns a Promise.
*/
testConnection: function();
/**
* This function will spawn UI to ensure that the user has the right credentials
* to connect to the contact provider.
*
* @returns a Promise.
*/
authorize: function();
/**
* Called sometime after construction in order to let the connector do any
* start-up work. For some connectors, this might mean populating the cache
* if this is the first time being initted. This function will only be called
* if a connection has been successfully established.
*
* @returns a Promise.
*/
init: function();
/**
* Called to import records from this contact service.
*
* @returns a Promise.
*/
read: function();
/**
* If the contact provider must be polled for updates, this function will be called
* periodically by Ensemble to perform the polling. Incoming changes should be sent
* through the listener defined in the constructor.
*
* @returns a Promise.
*/
poll: function();
/** Statics **/
/**
* Returns whether or not more than one instance of this class can be created.
*/
static attribute boolean isSingleton;
/**
* Returns a chrome:// URL for the icon that represents this Connector.
*/
static attribute string iconURL;
/**
* Returns a human-readable name for the Connector class.
* Example: "Facebook Connector"
*/
static attribute string serviceName;
/**
* Returns a chrome:// URL for the UI for creating the initial connection for an instance.
*/
static attribute string createConnectionURI;
/**
* Returns a chrome:// URL for the UI for managing the connection for an instance.
*/
static attribute string managementURI;
/**
* Returns a JSON object for the default preferences that an instance should inherit.
*/
static attribute object defaultPrefs;
/**
* Returns a unique ID for this Connector class.
*/
static attribute string uniqueID;
}
A Backbone model that represents a record from a contact provider. Along with the usual Backbone functions, contains the following functions:
class Record {
attribute id;
Diff diff(aRecord);
applyDiff(aDiff);
merge(aRecord);
}
The listener object is called when items in a connector are imported, added, removed, or changed. The connector is responsible for maintaining a reference to the listener passed to it, and calling the correct functions when items are imported, added, removed or changed.
aListener = {
/**
* Called when a contact is *first* read in by the connector. This is not called when a contact is
* added on the server side, but only when the connector does a first-read of the service's contacts.
* It's called once per imported contact.
*
* @returns a Promise that resolves when the import work is done.
*/
onImport: function(aRecord);
onAdded: function(aRecord);
onChanged: function(aId, aDiff);
onRemoved: function(aId);
}
- First draft published - October 22nd, 2012
- Changes for caching - July 21, 2013