sharedb 3.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/agent.js CHANGED
@@ -1,8 +1,9 @@
1
1
  var hat = require('hat');
2
+ var ShareDBError = require('./error');
3
+ var logger = require('./logger');
4
+ var ACTIONS = require('./message-actions').ACTIONS;
2
5
  var types = require('./types');
3
6
  var util = require('./util');
4
- var logger = require('./logger');
5
- var ShareDBError = require('./error');
6
7
 
7
8
  var ERROR_CODE = ShareDBError.CODES;
8
9
 
@@ -58,7 +59,7 @@ function Agent(backend, stream) {
58
59
  this.custom = {};
59
60
 
60
61
  // Send the legacy message to initialize old clients with the random agent Id
61
- this.send(this._initMessage('init'));
62
+ this.send(this._initMessage(ACTIONS.initLegacy));
62
63
  }
63
64
  module.exports = Agent;
64
65
 
@@ -174,7 +175,7 @@ Agent.prototype._subscribeToQuery = function(emitter, queryId, collection, query
174
175
 
175
176
  var agent = this;
176
177
  emitter.onExtra = function(extra) {
177
- agent.send({a: 'q', id: queryId, extra: extra});
178
+ agent.send({a: ACTIONS.queryUpdate, id: queryId, extra: extra});
178
179
  };
179
180
 
180
181
  emitter.onDiff = function(diff) {
@@ -186,7 +187,7 @@ Agent.prototype._subscribeToQuery = function(emitter, queryId, collection, query
186
187
  }
187
188
  // Consider stripping the collection out of the data we send here
188
189
  // if it matches the query's collection.
189
- agent.send({a: 'q', id: queryId, diff: diff});
190
+ agent.send({a: ACTIONS.queryUpdate, id: queryId, diff: diff});
190
191
  };
191
192
 
192
193
  emitter.onError = function(err) {
@@ -250,7 +251,7 @@ Agent.prototype.send = function(message) {
250
251
 
251
252
  Agent.prototype._sendOp = function(collection, id, op) {
252
253
  var message = {
253
- a: 'op',
254
+ a: ACTIONS.op,
254
255
  c: collection,
255
256
  d: id,
256
257
  v: op.v,
@@ -354,22 +355,34 @@ Agent.prototype._open = function() {
354
355
 
355
356
  // Check a request to see if its valid. Returns an error if there's a problem.
356
357
  Agent.prototype._checkRequest = function(request) {
357
- if (request.a === 'qf' || request.a === 'qs' || request.a === 'qu') {
358
+ if (
359
+ request.a === ACTIONS.queryFetch ||
360
+ request.a === ACTIONS.querySubscribe ||
361
+ request.a === ACTIONS.queryUnsubscribe
362
+ ) {
358
363
  // Query messages need an ID property.
359
364
  if (typeof request.id !== 'number') return 'Missing query ID';
360
- } else if (request.a === 'op' || request.a === 'f' || request.a === 's' || request.a === 'u' || request.a === 'p') {
365
+ } else if (request.a === ACTIONS.op ||
366
+ request.a === ACTIONS.fetch ||
367
+ request.a === ACTIONS.subscribe ||
368
+ request.a === ACTIONS.unsubscribe ||
369
+ request.a === ACTIONS.presence) {
361
370
  // Doc-based request.
362
371
  if (request.c != null && typeof request.c !== 'string') return 'Invalid collection';
363
372
  if (request.d != null && typeof request.d !== 'string') return 'Invalid id';
364
373
 
365
- if (request.a === 'op' || request.a === 'p') {
374
+ if (request.a === ACTIONS.op || request.a === ACTIONS.presence) {
366
375
  if (request.v != null && (typeof request.v !== 'number' || request.v < 0)) return 'Invalid version';
367
376
  }
368
377
 
369
- if (request.a === 'p') {
378
+ if (request.a === ACTIONS.presence) {
370
379
  if (typeof request.id !== 'string') return 'Missing presence ID';
371
380
  }
372
- } else if (request.a === 'bf' || request.a === 'bs' || request.a === 'bu') {
381
+ } else if (
382
+ request.a === ACTIONS.bulkFetch ||
383
+ request.a === ACTIONS.bulkSubscribe ||
384
+ request.a === ACTIONS.bulkUnsubscribe
385
+ ) {
373
386
  // Bulk request
374
387
  if (request.c != null && typeof request.c !== 'string') return 'Invalid collection';
375
388
  if (typeof request.b !== 'object') return 'Invalid bulk subscribe data';
@@ -383,28 +396,28 @@ Agent.prototype._handleMessage = function(request, callback) {
383
396
  if (errMessage) return callback(new ShareDBError(ERROR_CODE.ERR_MESSAGE_BADLY_FORMED, errMessage));
384
397
 
385
398
  switch (request.a) {
386
- case 'hs':
399
+ case ACTIONS.handshake:
387
400
  if (request.id) this.src = request.id;
388
- return callback(null, this._initMessage('hs'));
389
- case 'qf':
401
+ return callback(null, this._initMessage(ACTIONS.handshake));
402
+ case ACTIONS.queryFetch:
390
403
  return this._queryFetch(request.id, request.c, request.q, getQueryOptions(request), callback);
391
- case 'qs':
404
+ case ACTIONS.querySubscribe:
392
405
  return this._querySubscribe(request.id, request.c, request.q, getQueryOptions(request), callback);
393
- case 'qu':
406
+ case ACTIONS.queryUnsubscribe:
394
407
  return this._queryUnsubscribe(request.id, callback);
395
- case 'bf':
408
+ case ACTIONS.bulkFetch:
396
409
  return this._fetchBulk(request.c, request.b, callback);
397
- case 'bs':
410
+ case ACTIONS.bulkSubscribe:
398
411
  return this._subscribeBulk(request.c, request.b, callback);
399
- case 'bu':
412
+ case ACTIONS.bulkUnsubscribe:
400
413
  return this._unsubscribeBulk(request.c, request.b, callback);
401
- case 'f':
414
+ case ACTIONS.fetch:
402
415
  return this._fetch(request.c, request.d, request.v, callback);
403
- case 's':
416
+ case ACTIONS.subscribe:
404
417
  return this._subscribe(request.c, request.d, request.v, callback);
405
- case 'u':
418
+ case ACTIONS.unsubscribe:
406
419
  return this._unsubscribe(request.c, request.d, callback);
407
- case 'op':
420
+ case ACTIONS.op:
408
421
  // Normalize the properties submitted
409
422
  var op = createClientOp(request, this._src());
410
423
  if (op.seq >= util.MAX_SAFE_INTEGER) {
@@ -415,11 +428,11 @@ Agent.prototype._handleMessage = function(request, callback) {
415
428
  }
416
429
  if (!op) return callback(new ShareDBError(ERROR_CODE.ERR_MESSAGE_BADLY_FORMED, 'Invalid op message'));
417
430
  return this._submit(request.c, request.d, op, callback);
418
- case 'nf':
431
+ case ACTIONS.snapshotFetch:
419
432
  return this._fetchSnapshot(request.c, request.d, request.v, callback);
420
- case 'nt':
433
+ case ACTIONS.snapshotFetchByTimestamp:
421
434
  return this._fetchSnapshotByTimestamp(request.c, request.d, request.ts, callback);
422
- case 'p':
435
+ case ACTIONS.presence:
423
436
  if (!this.backend.presenceEnabled) return;
424
437
  var presence = this._createPresence(request);
425
438
  if (presence.t && !util.supportsPresence(types.map[presence.t])) {
@@ -429,10 +442,10 @@ Agent.prototype._handleMessage = function(request, callback) {
429
442
  });
430
443
  }
431
444
  return this._broadcastPresence(presence, callback);
432
- case 'ps':
445
+ case ACTIONS.presenceSubscribe:
433
446
  if (!this.backend.presenceEnabled) return;
434
447
  return this._subscribePresence(request.ch, request.seq, callback);
435
- case 'pu':
448
+ case ACTIONS.presenceUnsubscribe:
436
449
  return this._unsubscribePresence(request.ch, request.seq, callback);
437
450
  default:
438
451
  callback(new ShareDBError(ERROR_CODE.ERR_MESSAGE_BADLY_FORMED, 'Invalid or unknown message'));
@@ -761,7 +774,7 @@ Agent.prototype._broadcastPresence = function(presence, callback) {
761
774
 
762
775
  Agent.prototype._createPresence = function(request) {
763
776
  return {
764
- a: 'p',
777
+ a: ACTIONS.presence,
765
778
  ch: request.ch,
766
779
  src: this._src(),
767
780
  id: request.id, // Presence ID, not Doc ID (which is 'd')
@@ -813,7 +826,7 @@ Agent.prototype._requestPresence = function(channel, callback) {
813
826
  Agent.prototype._handlePresenceData = function(presence) {
814
827
  if (presence.src === this._src()) return;
815
828
 
816
- if (presence.r) return this.send({a: 'pr', ch: presence.ch});
829
+ if (presence.r) return this.send({a: ACTIONS.presenceRequest, ch: presence.ch});
817
830
 
818
831
  var backend = this.backend;
819
832
  var context = {
@@ -824,7 +837,7 @@ Agent.prototype._handlePresenceData = function(presence) {
824
837
  backend.trigger(backend.MIDDLEWARE_ACTIONS.sendPresence, this, context, function(error) {
825
838
  if (error) {
826
839
  if (backend.doNotForwardSendPresenceErrorsToClient) backend.errorHandler(error, {agent: agent});
827
- else agent.send({a: 'p', ch: presence.ch, id: presence.id, error: getReplyErrorObject(error)});
840
+ else agent.send({a: ACTIONS.presence, ch: presence.ch, id: presence.id, error: getReplyErrorObject(error)});
828
841
  return;
829
842
  }
830
843
  agent.send(presence);
@@ -6,6 +6,7 @@ var SnapshotVersionRequest = require('./snapshot-request/snapshot-version-reques
6
6
  var SnapshotTimestampRequest = require('./snapshot-request/snapshot-timestamp-request');
7
7
  var emitter = require('../emitter');
8
8
  var ShareDBError = require('../error');
9
+ var ACTIONS = require('../message-actions').ACTIONS;
9
10
  var types = require('../types');
10
11
  var util = require('../util');
11
12
  var logger = require('../logger');
@@ -194,25 +195,25 @@ Connection.prototype.handleMessage = function(message) {
194
195
  // Switch on the message action. Most messages are for documents and are
195
196
  // handled in the doc class.
196
197
  switch (message.a) {
197
- case 'init':
198
+ case ACTIONS.initLegacy:
198
199
  // Client initialization packet
199
200
  return this._handleLegacyInit(message);
200
- case 'hs':
201
+ case ACTIONS.handshake:
201
202
  return this._handleHandshake(err, message);
202
- case 'qf':
203
+ case ACTIONS.queryFetch:
203
204
  var query = this.queries[message.id];
204
205
  if (query) query._handleFetch(err, message.data, message.extra);
205
206
  return;
206
- case 'qs':
207
+ case ACTIONS.querySubscribe:
207
208
  var query = this.queries[message.id];
208
209
  if (query) query._handleSubscribe(err, message.data, message.extra);
209
210
  return;
210
- case 'qu':
211
+ case ACTIONS.queryUnsubscribe:
211
212
  // Queries are removed immediately on calls to destroy, so we ignore
212
213
  // replies to query unsubscribes. Perhaps there should be a callback for
213
214
  // destroy, but this is currently unimplemented
214
215
  return;
215
- case 'q':
216
+ case ACTIONS.queryUpdate:
216
217
  // Query message. Pass this to the appropriate query object.
217
218
  var query = this.queries[message.id];
218
219
  if (!query) return;
@@ -221,36 +222,36 @@ Connection.prototype.handleMessage = function(message) {
221
222
  if (message.hasOwnProperty('extra')) query._handleExtra(message.extra);
222
223
  return;
223
224
 
224
- case 'bf':
225
+ case ACTIONS.bulkFetch:
225
226
  return this._handleBulkMessage(err, message, '_handleFetch');
226
- case 'bs':
227
- case 'bu':
227
+ case ACTIONS.bulkSubscribe:
228
+ case ACTIONS.bulkUnsubscribe:
228
229
  return this._handleBulkMessage(err, message, '_handleSubscribe');
229
230
 
230
- case 'nf':
231
- case 'nt':
231
+ case ACTIONS.snapshotFetch:
232
+ case ACTIONS.snapshotFetchByTimestamp:
232
233
  return this._handleSnapshotFetch(err, message);
233
234
 
234
- case 'f':
235
+ case ACTIONS.fetch:
235
236
  var doc = this.getExisting(message.c, message.d);
236
237
  if (doc) doc._handleFetch(err, message.data);
237
238
  return;
238
- case 's':
239
- case 'u':
239
+ case ACTIONS.subscribe:
240
+ case ACTIONS.unsubscribe:
240
241
  var doc = this.getExisting(message.c, message.d);
241
242
  if (doc) doc._handleSubscribe(err, message.data);
242
243
  return;
243
- case 'op':
244
+ case ACTIONS.op:
244
245
  var doc = this.getExisting(message.c, message.d);
245
246
  if (doc) doc._handleOp(err, message);
246
247
  return;
247
- case 'p':
248
+ case ACTIONS.presence:
248
249
  return this._handlePresence(err, message);
249
- case 'ps':
250
+ case ACTIONS.presenceSubscribe:
250
251
  return this._handlePresenceSubscribe(err, message);
251
- case 'pu':
252
+ case ACTIONS.presenceUnsubscribe:
252
253
  return this._handlePresenceUnsubscribe(err, message);
253
- case 'pr':
254
+ case ACTIONS.presenceRequest:
254
255
  return this._handlePresenceRequest(err, message);
255
256
 
256
257
  default:
@@ -416,7 +417,7 @@ Connection.prototype._sendBulk = function(action, collection, values) {
416
417
  }
417
418
  };
418
419
 
419
- Connection.prototype._sendAction = function(action, doc, version) {
420
+ Connection.prototype._sendActions = function(action, doc, version) {
420
421
  // Ensure the doc is registered so that it receives the reply message
421
422
  this._addDoc(doc);
422
423
  if (this.bulk) {
@@ -434,22 +435,22 @@ Connection.prototype._sendAction = function(action, doc, version) {
434
435
  };
435
436
 
436
437
  Connection.prototype.sendFetch = function(doc) {
437
- return this._sendAction('f', doc, doc.version);
438
+ return this._sendActions(ACTIONS.fetch, doc, doc.version);
438
439
  };
439
440
 
440
441
  Connection.prototype.sendSubscribe = function(doc) {
441
- return this._sendAction('s', doc, doc.version);
442
+ return this._sendActions(ACTIONS.subscribe, doc, doc.version);
442
443
  };
443
444
 
444
445
  Connection.prototype.sendUnsubscribe = function(doc) {
445
- return this._sendAction('u', doc);
446
+ return this._sendActions(ACTIONS.unsubscribe, doc);
446
447
  };
447
448
 
448
449
  Connection.prototype.sendOp = function(doc, op) {
449
450
  // Ensure the doc is registered so that it receives the reply message
450
451
  this._addDoc(doc);
451
452
  var message = {
452
- a: 'op',
453
+ a: ACTIONS.op,
453
454
  c: doc.collection,
454
455
  d: doc.id,
455
456
  v: doc.version,
@@ -553,7 +554,7 @@ Connection.prototype._destroyQuery = function(query) {
553
554
  // The callback should have the signature function(error, results, extra)
554
555
  // where results is a list of Doc objects.
555
556
  Connection.prototype.createFetchQuery = function(collection, q, options, callback) {
556
- return this._createQuery('qf', collection, q, options, callback);
557
+ return this._createQuery(ACTIONS.queryFetch, collection, q, options, callback);
557
558
  };
558
559
 
559
560
  // Create a subscribe query. Subscribe queries return with the initial data
@@ -563,7 +564,7 @@ Connection.prototype.createFetchQuery = function(collection, q, options, callbac
563
564
  // If present, the callback should have the signature function(error, results, extra)
564
565
  // where results is a list of Doc objects.
565
566
  Connection.prototype.createSubscribeQuery = function(collection, q, options, callback) {
566
- return this._createQuery('qs', collection, q, options, callback);
567
+ return this._createQuery(ACTIONS.querySubscribe, collection, q, options, callback);
567
568
  };
568
569
 
569
570
  Connection.prototype.hasPending = function() {
@@ -716,7 +717,7 @@ Connection.prototype._handleLegacyInit = function(message) {
716
717
  };
717
718
 
718
719
  Connection.prototype._initializeHandshake = function() {
719
- this.send({a: 'hs', id: this.id});
720
+ this.send({a: ACTIONS.handshake, id: this.id});
720
721
  };
721
722
 
722
723
  Connection.prototype._handleHandshake = function(error, message) {
@@ -1,4 +1,5 @@
1
1
  var emitter = require('../../emitter');
2
+ var ACTIONS = require('../../message-actions').ACTIONS;
2
3
  var util = require('../../util');
3
4
 
4
5
  module.exports = LocalPresence;
@@ -59,7 +60,7 @@ LocalPresence.prototype._ack = function(error, presenceVersion) {
59
60
 
60
61
  LocalPresence.prototype._message = function() {
61
62
  return {
62
- a: 'p',
63
+ a: ACTIONS.presence,
63
64
  ch: this.presence.channel,
64
65
  id: this.presenceId,
65
66
  p: this.value,
@@ -4,6 +4,7 @@ var RemotePresence = require('./remote-presence');
4
4
  var util = require('../../util');
5
5
  var async = require('async');
6
6
  var hat = require('hat');
7
+ var ACTIONS = require('../../message-actions').ACTIONS;
7
8
 
8
9
  module.exports = Presence;
9
10
  function Presence(connection, channel) {
@@ -70,7 +71,7 @@ Presence.prototype.destroy = function(callback) {
70
71
 
71
72
  Presence.prototype._sendSubscriptionAction = function(wantSubscribe, callback) {
72
73
  this.wantSubscribe = !!wantSubscribe;
73
- var action = this.wantSubscribe ? 'ps' : 'pu';
74
+ var action = this.wantSubscribe ? ACTIONS.presenceSubscribe : ACTIONS.presenceUnsubscribe;
74
75
  var seq = this.connection._presenceSeq++;
75
76
  this._subscriptionCallbacksBySeq[seq] = callback;
76
77
  if (this.connection.canSend) {
@@ -1,4 +1,5 @@
1
1
  var emitter = require('../emitter');
2
+ var ACTIONS = require('../message-actions').ACTIONS;
2
3
  var util = require('../util');
3
4
 
4
5
  // Queries are live requests to the database for particular sets of fields.
@@ -75,8 +76,8 @@ Query.prototype.send = function() {
75
76
  // Destroy the query object. Any subsequent messages for the query will be
76
77
  // ignored by the connection.
77
78
  Query.prototype.destroy = function(callback) {
78
- if (this.connection.canSend && this.action === 'qs') {
79
- this.connection.send({a: 'qu', id: this.id});
79
+ if (this.connection.canSend && this.action === ACTIONS.querySubscribe) {
80
+ this.connection.send({a: ACTIONS.queryUnsubscribe, id: this.id});
80
81
  }
81
82
  this.connection._destroyQuery(this);
82
83
  // There is a callback for consistency, but we don't actually wait for the
@@ -1,5 +1,6 @@
1
1
  var SnapshotRequest = require('./snapshot-request');
2
2
  var util = require('../../util');
3
+ var ACTIONS = require('../../message-actions').ACTIONS;
3
4
 
4
5
  module.exports = SnapshotTimestampRequest;
5
6
 
@@ -17,7 +18,7 @@ SnapshotTimestampRequest.prototype = Object.create(SnapshotRequest.prototype);
17
18
 
18
19
  SnapshotTimestampRequest.prototype._message = function() {
19
20
  return {
20
- a: 'nt',
21
+ a: ACTIONS.snapshotFetchByTimestamp,
21
22
  id: this.requestId,
22
23
  c: this.collection,
23
24
  d: this.id,
@@ -1,5 +1,6 @@
1
1
  var SnapshotRequest = require('./snapshot-request');
2
2
  var util = require('../../util');
3
+ var ACTIONS = require('../../message-actions').ACTIONS;
3
4
 
4
5
  module.exports = SnapshotVersionRequest;
5
6
 
@@ -17,7 +18,7 @@ SnapshotVersionRequest.prototype = Object.create(SnapshotRequest.prototype);
17
18
 
18
19
  SnapshotVersionRequest.prototype._message = function() {
19
20
  return {
20
- a: 'nf',
21
+ a: ACTIONS.snapshotFetch,
21
22
  id: this.requestId,
22
23
  c: this.collection,
23
24
  d: this.id,
package/lib/index.js CHANGED
@@ -9,6 +9,7 @@ Backend.logger = require('./logger');
9
9
  Backend.MemoryDB = require('./db/memory');
10
10
  Backend.MemoryMilestoneDB = require('./milestone-db/memory');
11
11
  Backend.MemoryPubSub = require('./pubsub/memory');
12
+ Backend.MESSAGE_ACTIONS = require('./message-actions').ACTIONS;
12
13
  Backend.MilestoneDB = require('./milestone-db');
13
14
  Backend.ot = require('./ot');
14
15
  Backend.projections = require('./projections');
@@ -0,0 +1,21 @@
1
+ exports.ACTIONS = {
2
+ initLegacy: 'init',
3
+ handshake: 'hs',
4
+ queryFetch: 'qf',
5
+ querySubscribe: 'qs',
6
+ queryUnsubscribe: 'qu',
7
+ queryUpdate: 'q',
8
+ bulkFetch: 'bf',
9
+ bulkSubscribe: 'bs',
10
+ bulkUnsubscribe: 'bu',
11
+ fetch: 'f',
12
+ subscribe: 's',
13
+ unsubscribe: 'u',
14
+ op: 'op',
15
+ snapshotFetch: 'nf',
16
+ snapshotFetchByTimestamp: 'nt',
17
+ presence: 'p',
18
+ presenceSubscribe: 'ps',
19
+ presenceUnsubscribe: 'pu',
20
+ presenceRequest: 'pr'
21
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sharedb",
3
- "version": "3.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "JSON OT database backend",
5
5
  "main": "lib/index.js",
6
6
  "dependencies": {
@@ -18,7 +18,7 @@
18
18
  "lolex": "^5.1.1",
19
19
  "mocha": "^8.2.1",
20
20
  "nyc": "^14.1.1",
21
- "ot-json0-v2": "ottypes/json0",
21
+ "ot-json0-v2": "https://github.com/ottypes/json0#90a3ae26364c4fa3b19b6df34dad46707a704421",
22
22
  "ot-json1": "^0.3.0",
23
23
  "rich-text": "^4.1.0",
24
24
  "sharedb-legacy": "npm:sharedb@=1.1.0",