sharedb 2.2.2 → 2.2.3

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/README.md CHANGED
@@ -9,8 +9,9 @@ ShareDB is a realtime database backend based on [Operational Transformation
9
9
  documents. It is the realtime backend for the [DerbyJS web application
10
10
  framework](http://derbyjs.com/).
11
11
 
12
- For questions, discussion and announcements, join the [ShareJS mailing
13
- list](https://groups.google.com/forum/?fromgroups#!forum/sharejs) or [check the FAQ](./docs/faq.md).
12
+ For help, questions, discussion and announcements, join the [ShareJS mailing
13
+ list](https://groups.google.com/forum/?fromgroups#!forum/sharejs) or [read the documentation](https://share.github.io/sharedb/
14
+ ).
14
15
 
15
16
  Please report any bugs you find to the [issue
16
17
  tracker](https://github.com/share/sharedb/issues).
package/lib/ot.js CHANGED
@@ -221,11 +221,18 @@ function normalizeLegacyJson0Ops(snapshot, json0Op) {
221
221
  if (snapshot.type !== types.defaultType.uri) return;
222
222
  var components = json0Op.op;
223
223
  if (!components) return;
224
+ var data = snapshot.data;
225
+
226
+ // type.apply() makes no guarantees about mutating the original data, so
227
+ // we need to clone. However, we only need to apply() if we have multiple
228
+ // components, so avoid cloning if we don't have to.
229
+ if (components.length > 1) data = util.clone(data);
230
+
224
231
  for (var i = 0; i < components.length; i++) {
225
232
  var component = components[i];
226
233
  if (typeof component.lm === 'string') component.lm = +component.lm;
227
234
  var path = component.p;
228
- var element = snapshot.data;
235
+ var element = data;
229
236
  for (var j = 0; j < path.length; j++) {
230
237
  var key = path[j];
231
238
  // https://github.com/ottypes/json0/blob/73db17e86adc5d801951d1a69453b01382e66c7d/lib/json0.js#L21
@@ -234,5 +241,10 @@ function normalizeLegacyJson0Ops(snapshot, json0Op) {
234
241
  else if (element.constructor === Object) path[j] = key.toString();
235
242
  element = element[key];
236
243
  }
244
+
245
+ // Apply to update the snapshot, so we can correctly check the path for
246
+ // the next component. We don't need to do this on the final iteration,
247
+ // since there's no more ops.
248
+ if (i < components.length - 1) data = types.defaultType.apply(data, [component]);
237
249
  }
238
250
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sharedb",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "description": "JSON OT database backend",
5
5
  "main": "lib/index.js",
6
6
  "dependencies": {
@@ -496,4 +496,50 @@ describe('SnapshotVersionRequest', function() {
496
496
  });
497
497
  });
498
498
  });
499
+
500
+ describe('invalid json0v2 path with multiple components', function() {
501
+ beforeEach(function(done) {
502
+ var doc = backend.connect().get('series', 'his-dark-materials');
503
+ async.series([
504
+ doc.create.bind(doc, [{}]),
505
+ doc.submitOp.bind(doc, [
506
+ {p: ['0', 'title'], oi: ''},
507
+ {p: ['0', 'title', 0], si: 'Northern Lights'}
508
+ ])
509
+ ], done);
510
+ });
511
+
512
+ describe('json0v1', function() {
513
+ it('fetches v2 with json0v1', function(done) {
514
+ backend.connect().fetchSnapshot('series', 'his-dark-materials', 2, function(error, snapshot) {
515
+ if (error) return done(error);
516
+ expect(snapshot.data).to.eql([{title: 'Northern Lights'}]);
517
+ done();
518
+ });
519
+ });
520
+ });
521
+
522
+ describe('json0v2', function() {
523
+ var defaultType;
524
+
525
+ beforeEach(function() {
526
+ defaultType = types.defaultType;
527
+ types.defaultType = json0v2;
528
+ types.register(json0v2);
529
+ });
530
+
531
+ afterEach(function() {
532
+ types.defaultType = defaultType;
533
+ types.register(defaultType);
534
+ });
535
+
536
+ it('fetches v2 with json0v2', function(done) {
537
+ backend.connect().fetchSnapshot('series', 'his-dark-materials', 2, function(error, snapshot) {
538
+ if (error) return done(error);
539
+ expect(snapshot.data).to.eql([{title: 'Northern Lights'}]);
540
+ done();
541
+ });
542
+ });
543
+ });
544
+ });
499
545
  });