-
Notifications
You must be signed in to change notification settings - Fork 454
Client API
Version 0.5.0
The client library lets you view and edit sharejs documents remotely using the server's socket.io frontend.
The API lets you do the following things:
- Get document snapshots
- Stream ops as they are submitted to a document
- Submit ops
The following stuff is currently unsupported:
- Getting historical operations
- Undo
- Listing documents
- Deleting documents
From node.js:
var sharejs = require('share').client;
sharejs.open('hello', 'text', 'http://example.com:8000/sjs', function(error, doc) {
...
});
From a website hosted by the share.js server:
<script src="/socket.io/socket.io.js"></script>
<script src="/share/share.js"></script>
<script>
sharejs.open('hello', 'text', function(error, doc) {
...
});
</script>
From a website hosted elsewhere:
<script src="http://example.com:8000/socket.io/socket.io.js"></script>
<script src="http://example.com:8000/share/share.js"></script>
<script>
sharejs.open('hello', 'text', 'http://example.com:8000/sjs', function(error, doc) {
...
});
</script>
-
open()
sharejs.open(docName, type, [url], function(error, doc){ ... })
Open a sharejs document with the given name and type. A handle to the document will be passed to the callback once its snapshot has been received by the server.
This method is a convenience method for
connection.open
, below.If the document does not already exist, it will be created using the specified type before being returned to the callback. If the document already exists and has a different type, an error will be passed to the callback.
Document names are case sensitive and cannot contain slashes (
/
).The type can be specified as a string (eg,
'text'
) or an object (eg,require('share').types.text
).The URL is a socket.io URL. It looks like
http[s]://hostname:port/sjs
. (Note thesjs
on the end specifies the default sharejs resource identifier. This may change in a future version.)The URL is only needed when using sharejs from a node.js app or when you're running sharejs from a different machine than the page's host. In the browser, it will default to 'PROTO://HOSTNAME:PORT/sjs'. If the default is fine, leave it out.
You only need to manually use connections if you're doing something tricky. Most people should just call sharejs.open
.
NOTE: Connections don't currently automatically reconnect when disconnected. If this is important to you, please help out :)
A Connection manages a connection to a share.js server. You only need one connection to a given server no matter how many documents you have open.
If you use the sharejs.open
API (above), connections are created for you automatically.
-
new Connection()
connection = new sharejs.Connection(host, port)
Create a connection to a sharejs server running at the default hostname & path. Set basePath to whatever the socket.io basepath is set to in the server (blank if you haven't changed it).
-
connection.open()
connection.open(docName, type, [url], function(error, doc) {...})
Open a sharejs document with the given name and type. A handle to the document will be passed to the callback once its snapshot has been received by the server.
If all you want to do is open documents of a known type on a known server, I recommend using
sharejs.open
, above. This way, the connection will be managed for you.If the document does not already exist, it will be created using the specified type before being returned to the callback. If the document already exists and has a different type, an error will be passed to the callback.
Document names are case sensitive.
The type can be specified as a string (eg,
'text'
) or an object (eg,require('share').types.text
). -
connection.openExisting()
connection.openExisting(docName, function(error, doc) {...})
Open an existing document. If the document does not exist, the callback is passed
null
. -
connection.disconnect()
connection.disconnect()
Disconnect from the server. Once disconnected, all documents currently open through the connection will stop sending and receiving ops. There is no reconnect.
All open methods in the client return Document
objects. These objects are handles to documents sitting on the share.js server. The document object implements client-side OT so you don't have to worry about concurrency in your app.
You cannot create documents directly. Instead, use any of the open()
methods described above.
For documentation on using JSON documents, see JSON Client API. All the methods in the JSON client API are accessible through the document object if you're using a JSON document.
-
doc.getText() (Text documents only)
doc.getText()
Get the contents of the document as a string.
-
doc.insert() (Text documents only)
doc.insert(position, text, [function(error, appliedOp) {...}])
Insert the given text at the specified position in the document. The position is an integer specifying the character position from the start of the document.
Eg: Given a document with text
abc
, insert ad
at the end by callingdoc.insert(3,'d')
.Locally, the document is edited immediately. (If you call getText() straight after doc.insert, your document will already have been edited). The callback is called once the server has acknowledged the operation.
The world won't end if you don't, but for consistency you should use unix line endings.
If you make multiple calls to
doc.insert()
,doc.del()
anddoc.submitOp()
within the same event handler, your edits will be composed together and sent as a single operation. -
doc.del() (Text documents only)
doc.del(position, length, [function(error, appliedOp) {...}])
Delete
length
characters from the document at the specified position in the document. The position is an integer specifying the character position from the start of the document.Eg: Given a document with text
abcd
, delete thed
at the end by callingdoc.del(1, 3)
.Locally, the document is edited immediately. (If you call getText() straight after doc.insert, your document will already have been edited). The callback is called once the server has acknowledged the operation.
If you make multiple calls to
doc.insert()
,doc.del()
anddoc.submitOp()
within the same event handler, your edits will be composed together and sent as a single operation. -
doc.snapshot
doc.snapshot
The document's current state. For text documents, this is a string containing the contents of the document. This snapshot includes any modifications made locally which have not yet propagated to the server.
-
doc.version
doc.version
The document's version on the server. This is a number counting from 1 when the document was first created. It is incremented each time an operation is applied to the document on the server. The client will compose together multiple operations if they happen close together, so be aware may not be incremented as often as you expect it to.
-
doc.type
doc.type
The OT type of the document. This object contains the document type's OT functions. See the section on OT types for details.
-
doc.submitOp()
doc.submitOp(op, [function(error, appliedOp) {...}])
This is a pretty low level function for editing documents. If you're editing text, you probably want to use the high level API methods (insert(), del(), etc) instead.
This has been changed since v0.3 - the optional version parameter was removed.
Submit an operation to the document. The operation must be valid given the document's type. The operation will be applied to the local document snapshot immediately (before submitOp returns).
It will be applied to the server as soon as possible (only one op is allowed in-flight at a time). If multiple ops are applied within the same scheduler frame, they are composed together before being sent. Ie, if you call
doc.submit(op1); doc.submit(op2);
, the client will composeop1
andop2
for you.If a callback is specified, it will be called once the server has acknowledged the operation. It is passed the operation as it was accepted by the server, or an error message in the second argument. This will not necessarily be the same as the op that was submitted originally. You don't need to wait for the callback before calling submitOp() again.
If the op is invalid, submitOp will throw an exception and the document will not be modified. If your code generating the ops is correct, this should never happen.
I expect most people will never use the callback field of submitOp. Just call
submitOp(myCoolOp)
as much as you like and the client code should take care of everything else.Text operations look like this:
Insert 'Some text' at position 100 in the document:
{i:'Some text', p:100}
Delete 'blargh' at position 300:
{d:'blargh', p:300}
Multiple changes can be specified in the same operation. This deletes 'Sam' in the document at position 10 in the document string, and replaces it with 'Seph' at the same location.
[{d:'Sam', p:10}, {i:'Seph', p:10}]
See the documentation on types for more detail, as well as op specs for other types.
-
doc.close()
doc.close([callback])
Close the document. When the server acknowledges that the document has been closed, the callback is called and the
'closed'
event is emitted.
The document is a simple event emitter. Use doc.on(event, callback)
to register callbacks and doc.removeListener(event, callback)
to remove them.
-
insert
doc.on('insert', function(position, text) {})
(Text documents only) Emitted whenever a remote client inserts
text
atposition
. Positions are specified as character offsets from the start of the document.If a remote client makes multiple changes to the document within a single operation, the document snapshot will be updated with all changes before your callbacks are called.
Eg: Given a document
ace
, a client inserts ab
and ad
to make the documentabcde
. You have registereddoc.on('insert', foo)
. ShareJS will callfoo('b', 1)
thenfoo('d', 3)
. -
delete
doc.on('delete', function(position, text) {})
(Text documents only) Emitted whenever a remote client deletes
text
atposition
. Positions are specified as character offsets from the start of the document.If a remote client makes multiple changes to the document within a single operation, the document snapshot will be updated with all changes before your callbacks are called.
Eg: Given a document
abcde
, a client deletes ab
and ad
to make the documentace
. You have registereddoc.on('delete', foo)
. ShareJS will callfoo('b', 1)
thenfoo('d', 2)
. -
remoteop
doc.on('remoteop', function(op) {})
Emitted each time the document is changed remotely with the op from the server. If you're hooking sharejs up to an editor, listen to this event and update the contents of the editor window accordingly.
By the time your callback is called, the document's
snapshot
andversion
will have been updated by the change. If you want, your listener method can just read the snapshot out of the document again. -
change
doc.on('change', function(op) {})
Emitted each time the document is changed either locally or remotely. The op which modified the document is passed to the callback.
-
closed
doc.on('closed', function() {})
Emitted when the server has acknowledged that the document is closed.