mongodb-livedata-server 0.1.3 → 0.1.5

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.
Files changed (92) hide show
  1. package/README.md +2 -2
  2. package/dist/livedata_server.d.ts +4 -4
  3. package/dist/livedata_server.js +11 -11
  4. package/dist/meteor/binary-heap/max_heap.d.ts +31 -31
  5. package/dist/meteor/binary-heap/max_heap.js +186 -186
  6. package/dist/meteor/binary-heap/min_heap.d.ts +6 -6
  7. package/dist/meteor/binary-heap/min_heap.js +17 -17
  8. package/dist/meteor/binary-heap/min_max_heap.d.ts +11 -11
  9. package/dist/meteor/binary-heap/min_max_heap.js +48 -48
  10. package/dist/meteor/callback-hook/hook.d.ts +11 -11
  11. package/dist/meteor/callback-hook/hook.js +78 -78
  12. package/dist/meteor/ddp/crossbar.d.ts +15 -15
  13. package/dist/meteor/ddp/crossbar.js +136 -136
  14. package/dist/meteor/ddp/heartbeat.d.ts +19 -19
  15. package/dist/meteor/ddp/heartbeat.js +77 -77
  16. package/dist/meteor/ddp/livedata_server.d.ts +141 -142
  17. package/dist/meteor/ddp/livedata_server.js +403 -403
  18. package/dist/meteor/ddp/method-invocation.d.ts +35 -35
  19. package/dist/meteor/ddp/method-invocation.js +72 -72
  20. package/dist/meteor/ddp/random-stream.d.ts +8 -8
  21. package/dist/meteor/ddp/random-stream.js +100 -100
  22. package/dist/meteor/ddp/session-collection-view.d.ts +20 -20
  23. package/dist/meteor/ddp/session-collection-view.js +106 -106
  24. package/dist/meteor/ddp/session-document-view.d.ts +8 -8
  25. package/dist/meteor/ddp/session-document-view.js +82 -82
  26. package/dist/meteor/ddp/session.d.ts +75 -75
  27. package/dist/meteor/ddp/session.js +590 -590
  28. package/dist/meteor/ddp/stream_server.d.ts +20 -21
  29. package/dist/meteor/ddp/stream_server.js +181 -181
  30. package/dist/meteor/ddp/subscription.d.ts +94 -94
  31. package/dist/meteor/ddp/subscription.js +370 -370
  32. package/dist/meteor/ddp/utils.d.ts +8 -8
  33. package/dist/meteor/ddp/utils.js +104 -104
  34. package/dist/meteor/ddp/writefence.d.ts +20 -20
  35. package/dist/meteor/ddp/writefence.js +111 -111
  36. package/dist/meteor/diff-sequence/diff.d.ts +17 -17
  37. package/dist/meteor/diff-sequence/diff.js +257 -257
  38. package/dist/meteor/ejson/ejson.d.ts +82 -82
  39. package/dist/meteor/ejson/ejson.js +568 -569
  40. package/dist/meteor/ejson/stringify.d.ts +2 -2
  41. package/dist/meteor/ejson/stringify.js +119 -119
  42. package/dist/meteor/ejson/utils.d.ts +12 -12
  43. package/dist/meteor/ejson/utils.js +42 -42
  44. package/dist/meteor/mongo/caching_change_observer.d.ts +16 -16
  45. package/dist/meteor/mongo/caching_change_observer.js +63 -63
  46. package/dist/meteor/mongo/doc_fetcher.d.ts +7 -7
  47. package/dist/meteor/mongo/doc_fetcher.js +53 -53
  48. package/dist/meteor/mongo/geojson_utils.d.ts +3 -3
  49. package/dist/meteor/mongo/geojson_utils.js +40 -41
  50. package/dist/meteor/mongo/live_connection.d.ts +28 -28
  51. package/dist/meteor/mongo/live_connection.js +264 -264
  52. package/dist/meteor/mongo/live_cursor.d.ts +25 -25
  53. package/dist/meteor/mongo/live_cursor.js +60 -60
  54. package/dist/meteor/mongo/minimongo_common.d.ts +84 -84
  55. package/dist/meteor/mongo/minimongo_common.js +1998 -1998
  56. package/dist/meteor/mongo/minimongo_matcher.d.ts +23 -23
  57. package/dist/meteor/mongo/minimongo_matcher.js +283 -283
  58. package/dist/meteor/mongo/minimongo_sorter.d.ts +16 -16
  59. package/dist/meteor/mongo/minimongo_sorter.js +268 -268
  60. package/dist/meteor/mongo/observe_driver_utils.d.ts +9 -9
  61. package/dist/meteor/mongo/observe_driver_utils.js +72 -73
  62. package/dist/meteor/mongo/observe_multiplexer.d.ts +46 -46
  63. package/dist/meteor/mongo/observe_multiplexer.js +203 -203
  64. package/dist/meteor/mongo/oplog-observe-driver.d.ts +68 -68
  65. package/dist/meteor/mongo/oplog-observe-driver.js +918 -918
  66. package/dist/meteor/mongo/oplog_tailing.d.ts +35 -35
  67. package/dist/meteor/mongo/oplog_tailing.js +352 -352
  68. package/dist/meteor/mongo/oplog_v2_converter.d.ts +1 -1
  69. package/dist/meteor/mongo/oplog_v2_converter.js +125 -126
  70. package/dist/meteor/mongo/polling_observe_driver.d.ts +30 -30
  71. package/dist/meteor/mongo/polling_observe_driver.js +216 -221
  72. package/dist/meteor/mongo/synchronous-cursor.d.ts +17 -17
  73. package/dist/meteor/mongo/synchronous-cursor.js +261 -261
  74. package/dist/meteor/mongo/synchronous-queue.d.ts +13 -13
  75. package/dist/meteor/mongo/synchronous-queue.js +110 -110
  76. package/dist/meteor/ordered-dict/ordered_dict.d.ts +31 -31
  77. package/dist/meteor/ordered-dict/ordered_dict.js +198 -198
  78. package/dist/meteor/random/AbstractRandomGenerator.d.ts +42 -42
  79. package/dist/meteor/random/AbstractRandomGenerator.js +92 -92
  80. package/dist/meteor/random/AleaRandomGenerator.d.ts +13 -13
  81. package/dist/meteor/random/AleaRandomGenerator.js +90 -90
  82. package/dist/meteor/random/NodeRandomGenerator.d.ts +16 -16
  83. package/dist/meteor/random/NodeRandomGenerator.js +42 -42
  84. package/dist/meteor/random/createAleaGenerator.d.ts +2 -2
  85. package/dist/meteor/random/createAleaGenerator.js +32 -32
  86. package/dist/meteor/random/createRandom.d.ts +1 -1
  87. package/dist/meteor/random/createRandom.js +22 -22
  88. package/dist/meteor/random/main.d.ts +1 -1
  89. package/dist/meteor/random/main.js +12 -12
  90. package/dist/meteor/types.d.ts +1 -1
  91. package/dist/meteor/types.js +2 -2
  92. package/package.json +5 -5
@@ -1,257 +1,257 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DiffSequence = void 0;
4
- const ejson_1 = require("../ejson/ejson");
5
- exports.DiffSequence = {};
6
- const hasOwn = Object.prototype.hasOwnProperty;
7
- function isObjEmpty(obj) {
8
- for (let key in Object(obj)) {
9
- if (hasOwn.call(obj, key)) {
10
- return false;
11
- }
12
- }
13
- return true;
14
- }
15
- // ordered: bool.
16
- // old_results and new_results: collections of documents.
17
- // if ordered, they are arrays.
18
- // if unordered, they are IdMaps
19
- exports.DiffSequence.diffQueryChanges = function (ordered, oldResults, newResults, observer, options) {
20
- if (ordered)
21
- exports.DiffSequence.diffQueryOrderedChanges(oldResults, newResults, observer, options);
22
- else
23
- exports.DiffSequence.diffQueryUnorderedChanges(oldResults, newResults, observer, options);
24
- };
25
- exports.DiffSequence.diffQueryUnorderedChanges = function (oldResults, newResults, observer, options) {
26
- options = options || {};
27
- var projectionFn = options.projectionFn || ejson_1.clone;
28
- if (observer.movedBefore) {
29
- throw new Error("_diffQueryUnordered called with a movedBefore observer!");
30
- }
31
- newResults.forEach(function (newDoc, id) {
32
- var oldDoc = oldResults.get(id);
33
- if (oldDoc) {
34
- if (observer.changed && !(0, ejson_1.equals)(oldDoc, newDoc)) {
35
- var projectedNew = projectionFn(newDoc);
36
- var projectedOld = projectionFn(oldDoc);
37
- var changedFields = exports.DiffSequence.makeChangedFields(projectedNew, projectedOld);
38
- if (!isObjEmpty(changedFields)) {
39
- observer.changed(id, changedFields);
40
- }
41
- }
42
- }
43
- else if (observer.added) {
44
- var fields = projectionFn(newDoc);
45
- delete fields._id;
46
- observer.added(newDoc._id, fields);
47
- }
48
- });
49
- if (observer.removed) {
50
- oldResults.forEach(function (oldDoc, id) {
51
- if (!newResults.has(id))
52
- observer.removed(id);
53
- });
54
- }
55
- };
56
- exports.DiffSequence.diffQueryOrderedChanges = function (old_results, new_results, observer, options) {
57
- options = options || {};
58
- var projectionFn = options.projectionFn || ejson_1.clone;
59
- var new_presence_of_id = {};
60
- new_results.forEach(function (doc) {
61
- if (new_presence_of_id[doc._id])
62
- console.log("Duplicate _id in new_results");
63
- new_presence_of_id[doc._id] = true;
64
- });
65
- var old_index_of_id = {};
66
- old_results.forEach(function (doc, i) {
67
- if (doc._id in old_index_of_id)
68
- console.log("Duplicate _id in old_results");
69
- old_index_of_id[doc._id] = i;
70
- });
71
- // ALGORITHM:
72
- //
73
- // To determine which docs should be considered "moved" (and which
74
- // merely change position because of other docs moving) we run
75
- // a "longest common subsequence" (LCS) algorithm. The LCS of the
76
- // old doc IDs and the new doc IDs gives the docs that should NOT be
77
- // considered moved.
78
- // To actually call the appropriate callbacks to get from the old state to the
79
- // new state:
80
- // First, we call removed() on all the items that only appear in the old
81
- // state.
82
- // Then, once we have the items that should not move, we walk through the new
83
- // results array group-by-group, where a "group" is a set of items that have
84
- // moved, anchored on the end by an item that should not move. One by one, we
85
- // move each of those elements into place "before" the anchoring end-of-group
86
- // item, and fire changed events on them if necessary. Then we fire a changed
87
- // event on the anchor, and move on to the next group. There is always at
88
- // least one group; the last group is anchored by a virtual "null" id at the
89
- // end.
90
- // Asymptotically: O(N k) where k is number of ops, or potentially
91
- // O(N log N) if inner loop of LCS were made to be binary search.
92
- //////// LCS (longest common sequence, with respect to _id)
93
- // (see Wikipedia article on Longest Increasing Subsequence,
94
- // where the LIS is taken of the sequence of old indices of the
95
- // docs in new_results)
96
- //
97
- // unmoved: the output of the algorithm; members of the LCS,
98
- // in the form of indices into new_results
99
- var unmoved = [];
100
- // max_seq_len: length of LCS found so far
101
- var max_seq_len = 0;
102
- // seq_ends[i]: the index into new_results of the last doc in a
103
- // common subsequence of length of i+1 <= max_seq_len
104
- var N = new_results.length;
105
- var seq_ends = new Array(N);
106
- // ptrs: the common subsequence ending with new_results[n] extends
107
- // a common subsequence ending with new_results[ptr[n]], unless
108
- // ptr[n] is -1.
109
- var ptrs = new Array(N);
110
- // virtual sequence of old indices of new results
111
- var old_idx_seq = function (i_new) {
112
- return old_index_of_id[new_results[i_new]._id];
113
- };
114
- // for each item in new_results, use it to extend a common subsequence
115
- // of length j <= max_seq_len
116
- for (var i = 0; i < N; i++) {
117
- if (old_index_of_id[new_results[i]._id] !== undefined) {
118
- var j = max_seq_len;
119
- // this inner loop would traditionally be a binary search,
120
- // but scanning backwards we will likely find a subseq to extend
121
- // pretty soon, bounded for example by the total number of ops.
122
- // If this were to be changed to a binary search, we'd still want
123
- // to scan backwards a bit as an optimization.
124
- while (j > 0) {
125
- if (old_idx_seq(seq_ends[j - 1]) < old_idx_seq(i))
126
- break;
127
- j--;
128
- }
129
- ptrs[i] = (j === 0 ? -1 : seq_ends[j - 1]);
130
- seq_ends[j] = i;
131
- if (j + 1 > max_seq_len)
132
- max_seq_len = j + 1;
133
- }
134
- }
135
- // pull out the LCS/LIS into unmoved
136
- var idx = (max_seq_len === 0 ? -1 : seq_ends[max_seq_len - 1]);
137
- while (idx >= 0) {
138
- unmoved.push(idx);
139
- idx = ptrs[idx];
140
- }
141
- // the unmoved item list is built backwards, so fix that
142
- unmoved.reverse();
143
- // the last group is always anchored by the end of the result list, which is
144
- // an id of "null"
145
- unmoved.push(new_results.length);
146
- old_results.forEach(function (doc) {
147
- if (!new_presence_of_id[doc._id])
148
- observer.removed && observer.removed(doc._id);
149
- });
150
- // for each group of things in the new_results that is anchored by an unmoved
151
- // element, iterate through the things before it.
152
- var startOfGroup = 0;
153
- unmoved.forEach(function (endOfGroup) {
154
- var groupId = new_results[endOfGroup] ? new_results[endOfGroup]._id : null;
155
- var oldDoc, newDoc, fields, projectedNew, projectedOld;
156
- for (var i = startOfGroup; i < endOfGroup; i++) {
157
- newDoc = new_results[i];
158
- if (!hasOwn.call(old_index_of_id, newDoc._id)) {
159
- fields = projectionFn(newDoc);
160
- delete fields._id;
161
- observer.addedBefore && observer.addedBefore(newDoc._id, fields, groupId);
162
- observer.added && observer.added(newDoc._id, fields);
163
- }
164
- else {
165
- // moved
166
- oldDoc = old_results[old_index_of_id[newDoc._id]];
167
- projectedNew = projectionFn(newDoc);
168
- projectedOld = projectionFn(oldDoc);
169
- fields = exports.DiffSequence.makeChangedFields(projectedNew, projectedOld);
170
- if (!isObjEmpty(fields)) {
171
- observer.changed && observer.changed(newDoc._id, fields);
172
- }
173
- observer.movedBefore && observer.movedBefore(newDoc._id, groupId);
174
- }
175
- }
176
- if (groupId) {
177
- newDoc = new_results[endOfGroup];
178
- oldDoc = old_results[old_index_of_id[newDoc._id]];
179
- projectedNew = projectionFn(newDoc);
180
- projectedOld = projectionFn(oldDoc);
181
- fields = exports.DiffSequence.makeChangedFields(projectedNew, projectedOld);
182
- if (!isObjEmpty(fields)) {
183
- observer.changed && observer.changed(newDoc._id, fields);
184
- }
185
- }
186
- startOfGroup = endOfGroup + 1;
187
- });
188
- };
189
- // General helper for diff-ing two objects.
190
- // callbacks is an object like so:
191
- // { leftOnly: function (key, leftValue) {...},
192
- // rightOnly: function (key, rightValue) {...},
193
- // both: function (key, leftValue, rightValue) {...},
194
- // }
195
- exports.DiffSequence.diffObjects = function (left, right, callbacks) {
196
- Object.keys(left).forEach(key => {
197
- const leftValue = left[key];
198
- if (hasOwn.call(right, key)) {
199
- callbacks.both && callbacks.both(key, leftValue, right[key]);
200
- }
201
- else {
202
- callbacks.leftOnly && callbacks.leftOnly(key, leftValue);
203
- }
204
- });
205
- if (callbacks.rightOnly) {
206
- Object.keys(right).forEach(key => {
207
- const rightValue = right[key];
208
- if (!hasOwn.call(left, key)) {
209
- callbacks.rightOnly(key, rightValue);
210
- }
211
- });
212
- }
213
- };
214
- exports.DiffSequence.diffMaps = function (left, right, callbacks) {
215
- left.forEach(function (leftValue, key) {
216
- if (right.has(key)) {
217
- callbacks.both && callbacks.both(key, leftValue, right.get(key));
218
- }
219
- else {
220
- callbacks.leftOnly && callbacks.leftOnly(key, leftValue);
221
- }
222
- });
223
- if (callbacks.rightOnly) {
224
- right.forEach(function (rightValue, key) {
225
- if (!left.has(key)) {
226
- callbacks.rightOnly(key, rightValue);
227
- }
228
- });
229
- }
230
- };
231
- exports.DiffSequence.makeChangedFields = function (newDoc, oldDoc) {
232
- var fields = {};
233
- exports.DiffSequence.diffObjects(oldDoc, newDoc, {
234
- leftOnly: function (key, value) {
235
- fields[key] = undefined;
236
- },
237
- rightOnly: function (key, value) {
238
- fields[key] = value;
239
- },
240
- both: function (key, leftValue, rightValue) {
241
- if (!(0, ejson_1.equals)(leftValue, rightValue))
242
- fields[key] = rightValue;
243
- }
244
- });
245
- return fields;
246
- };
247
- exports.DiffSequence.applyChanges = function (doc, changeFields) {
248
- Object.keys(changeFields).forEach(key => {
249
- const value = changeFields[key];
250
- if (typeof value === "undefined") {
251
- delete doc[key];
252
- }
253
- else {
254
- doc[key] = value;
255
- }
256
- });
257
- };
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DiffSequence = void 0;
4
+ const ejson_1 = require("../ejson/ejson");
5
+ exports.DiffSequence = {};
6
+ const hasOwn = Object.prototype.hasOwnProperty;
7
+ function isObjEmpty(obj) {
8
+ for (let key in Object(obj)) {
9
+ if (hasOwn.call(obj, key)) {
10
+ return false;
11
+ }
12
+ }
13
+ return true;
14
+ }
15
+ // ordered: bool.
16
+ // old_results and new_results: collections of documents.
17
+ // if ordered, they are arrays.
18
+ // if unordered, they are IdMaps
19
+ exports.DiffSequence.diffQueryChanges = function (ordered, oldResults, newResults, observer, options) {
20
+ if (ordered)
21
+ exports.DiffSequence.diffQueryOrderedChanges(oldResults, newResults, observer, options);
22
+ else
23
+ exports.DiffSequence.diffQueryUnorderedChanges(oldResults, newResults, observer, options);
24
+ };
25
+ exports.DiffSequence.diffQueryUnorderedChanges = function (oldResults, newResults, observer, options) {
26
+ options = options || {};
27
+ var projectionFn = options.projectionFn || ejson_1.clone;
28
+ if (observer.movedBefore) {
29
+ throw new Error("_diffQueryUnordered called with a movedBefore observer!");
30
+ }
31
+ newResults.forEach(function (newDoc, id) {
32
+ var oldDoc = oldResults.get(id);
33
+ if (oldDoc) {
34
+ if (observer.changed && !(0, ejson_1.equals)(oldDoc, newDoc)) {
35
+ var projectedNew = projectionFn(newDoc);
36
+ var projectedOld = projectionFn(oldDoc);
37
+ var changedFields = exports.DiffSequence.makeChangedFields(projectedNew, projectedOld);
38
+ if (!isObjEmpty(changedFields)) {
39
+ observer.changed(id, changedFields);
40
+ }
41
+ }
42
+ }
43
+ else if (observer.added) {
44
+ var fields = projectionFn(newDoc);
45
+ delete fields._id;
46
+ observer.added(newDoc._id, fields);
47
+ }
48
+ });
49
+ if (observer.removed) {
50
+ oldResults.forEach(function (oldDoc, id) {
51
+ if (!newResults.has(id))
52
+ observer.removed(id);
53
+ });
54
+ }
55
+ };
56
+ exports.DiffSequence.diffQueryOrderedChanges = function (old_results, new_results, observer, options) {
57
+ options = options || {};
58
+ var projectionFn = options.projectionFn || ejson_1.clone;
59
+ var new_presence_of_id = {};
60
+ new_results.forEach(function (doc) {
61
+ if (new_presence_of_id[doc._id])
62
+ console.log("Duplicate _id in new_results");
63
+ new_presence_of_id[doc._id] = true;
64
+ });
65
+ var old_index_of_id = {};
66
+ old_results.forEach(function (doc, i) {
67
+ if (doc._id in old_index_of_id)
68
+ console.log("Duplicate _id in old_results");
69
+ old_index_of_id[doc._id] = i;
70
+ });
71
+ // ALGORITHM:
72
+ //
73
+ // To determine which docs should be considered "moved" (and which
74
+ // merely change position because of other docs moving) we run
75
+ // a "longest common subsequence" (LCS) algorithm. The LCS of the
76
+ // old doc IDs and the new doc IDs gives the docs that should NOT be
77
+ // considered moved.
78
+ // To actually call the appropriate callbacks to get from the old state to the
79
+ // new state:
80
+ // First, we call removed() on all the items that only appear in the old
81
+ // state.
82
+ // Then, once we have the items that should not move, we walk through the new
83
+ // results array group-by-group, where a "group" is a set of items that have
84
+ // moved, anchored on the end by an item that should not move. One by one, we
85
+ // move each of those elements into place "before" the anchoring end-of-group
86
+ // item, and fire changed events on them if necessary. Then we fire a changed
87
+ // event on the anchor, and move on to the next group. There is always at
88
+ // least one group; the last group is anchored by a virtual "null" id at the
89
+ // end.
90
+ // Asymptotically: O(N k) where k is number of ops, or potentially
91
+ // O(N log N) if inner loop of LCS were made to be binary search.
92
+ //////// LCS (longest common sequence, with respect to _id)
93
+ // (see Wikipedia article on Longest Increasing Subsequence,
94
+ // where the LIS is taken of the sequence of old indices of the
95
+ // docs in new_results)
96
+ //
97
+ // unmoved: the output of the algorithm; members of the LCS,
98
+ // in the form of indices into new_results
99
+ var unmoved = [];
100
+ // max_seq_len: length of LCS found so far
101
+ var max_seq_len = 0;
102
+ // seq_ends[i]: the index into new_results of the last doc in a
103
+ // common subsequence of length of i+1 <= max_seq_len
104
+ var N = new_results.length;
105
+ var seq_ends = new Array(N);
106
+ // ptrs: the common subsequence ending with new_results[n] extends
107
+ // a common subsequence ending with new_results[ptr[n]], unless
108
+ // ptr[n] is -1.
109
+ var ptrs = new Array(N);
110
+ // virtual sequence of old indices of new results
111
+ var old_idx_seq = function (i_new) {
112
+ return old_index_of_id[new_results[i_new]._id];
113
+ };
114
+ // for each item in new_results, use it to extend a common subsequence
115
+ // of length j <= max_seq_len
116
+ for (var i = 0; i < N; i++) {
117
+ if (old_index_of_id[new_results[i]._id] !== undefined) {
118
+ var j = max_seq_len;
119
+ // this inner loop would traditionally be a binary search,
120
+ // but scanning backwards we will likely find a subseq to extend
121
+ // pretty soon, bounded for example by the total number of ops.
122
+ // If this were to be changed to a binary search, we'd still want
123
+ // to scan backwards a bit as an optimization.
124
+ while (j > 0) {
125
+ if (old_idx_seq(seq_ends[j - 1]) < old_idx_seq(i))
126
+ break;
127
+ j--;
128
+ }
129
+ ptrs[i] = (j === 0 ? -1 : seq_ends[j - 1]);
130
+ seq_ends[j] = i;
131
+ if (j + 1 > max_seq_len)
132
+ max_seq_len = j + 1;
133
+ }
134
+ }
135
+ // pull out the LCS/LIS into unmoved
136
+ var idx = (max_seq_len === 0 ? -1 : seq_ends[max_seq_len - 1]);
137
+ while (idx >= 0) {
138
+ unmoved.push(idx);
139
+ idx = ptrs[idx];
140
+ }
141
+ // the unmoved item list is built backwards, so fix that
142
+ unmoved.reverse();
143
+ // the last group is always anchored by the end of the result list, which is
144
+ // an id of "null"
145
+ unmoved.push(new_results.length);
146
+ old_results.forEach(function (doc) {
147
+ if (!new_presence_of_id[doc._id])
148
+ observer.removed && observer.removed(doc._id);
149
+ });
150
+ // for each group of things in the new_results that is anchored by an unmoved
151
+ // element, iterate through the things before it.
152
+ var startOfGroup = 0;
153
+ unmoved.forEach(function (endOfGroup) {
154
+ var groupId = new_results[endOfGroup] ? new_results[endOfGroup]._id : null;
155
+ var oldDoc, newDoc, fields, projectedNew, projectedOld;
156
+ for (var i = startOfGroup; i < endOfGroup; i++) {
157
+ newDoc = new_results[i];
158
+ if (!hasOwn.call(old_index_of_id, newDoc._id)) {
159
+ fields = projectionFn(newDoc);
160
+ delete fields._id;
161
+ observer.addedBefore && observer.addedBefore(newDoc._id, fields, groupId);
162
+ observer.added && observer.added(newDoc._id, fields);
163
+ }
164
+ else {
165
+ // moved
166
+ oldDoc = old_results[old_index_of_id[newDoc._id]];
167
+ projectedNew = projectionFn(newDoc);
168
+ projectedOld = projectionFn(oldDoc);
169
+ fields = exports.DiffSequence.makeChangedFields(projectedNew, projectedOld);
170
+ if (!isObjEmpty(fields)) {
171
+ observer.changed && observer.changed(newDoc._id, fields);
172
+ }
173
+ observer.movedBefore && observer.movedBefore(newDoc._id, groupId);
174
+ }
175
+ }
176
+ if (groupId) {
177
+ newDoc = new_results[endOfGroup];
178
+ oldDoc = old_results[old_index_of_id[newDoc._id]];
179
+ projectedNew = projectionFn(newDoc);
180
+ projectedOld = projectionFn(oldDoc);
181
+ fields = exports.DiffSequence.makeChangedFields(projectedNew, projectedOld);
182
+ if (!isObjEmpty(fields)) {
183
+ observer.changed && observer.changed(newDoc._id, fields);
184
+ }
185
+ }
186
+ startOfGroup = endOfGroup + 1;
187
+ });
188
+ };
189
+ // General helper for diff-ing two objects.
190
+ // callbacks is an object like so:
191
+ // { leftOnly: function (key, leftValue) {...},
192
+ // rightOnly: function (key, rightValue) {...},
193
+ // both: function (key, leftValue, rightValue) {...},
194
+ // }
195
+ exports.DiffSequence.diffObjects = function (left, right, callbacks) {
196
+ Object.keys(left).forEach(key => {
197
+ const leftValue = left[key];
198
+ if (hasOwn.call(right, key)) {
199
+ callbacks.both && callbacks.both(key, leftValue, right[key]);
200
+ }
201
+ else {
202
+ callbacks.leftOnly && callbacks.leftOnly(key, leftValue);
203
+ }
204
+ });
205
+ if (callbacks.rightOnly) {
206
+ Object.keys(right).forEach(key => {
207
+ const rightValue = right[key];
208
+ if (!hasOwn.call(left, key)) {
209
+ callbacks.rightOnly(key, rightValue);
210
+ }
211
+ });
212
+ }
213
+ };
214
+ exports.DiffSequence.diffMaps = function (left, right, callbacks) {
215
+ left.forEach(function (leftValue, key) {
216
+ if (right.has(key)) {
217
+ callbacks.both && callbacks.both(key, leftValue, right.get(key));
218
+ }
219
+ else {
220
+ callbacks.leftOnly && callbacks.leftOnly(key, leftValue);
221
+ }
222
+ });
223
+ if (callbacks.rightOnly) {
224
+ right.forEach(function (rightValue, key) {
225
+ if (!left.has(key)) {
226
+ callbacks.rightOnly(key, rightValue);
227
+ }
228
+ });
229
+ }
230
+ };
231
+ exports.DiffSequence.makeChangedFields = function (newDoc, oldDoc) {
232
+ var fields = {};
233
+ exports.DiffSequence.diffObjects(oldDoc, newDoc, {
234
+ leftOnly: function (key, value) {
235
+ fields[key] = undefined;
236
+ },
237
+ rightOnly: function (key, value) {
238
+ fields[key] = value;
239
+ },
240
+ both: function (key, leftValue, rightValue) {
241
+ if (!(0, ejson_1.equals)(leftValue, rightValue))
242
+ fields[key] = rightValue;
243
+ }
244
+ });
245
+ return fields;
246
+ };
247
+ exports.DiffSequence.applyChanges = function (doc, changeFields) {
248
+ Object.keys(changeFields).forEach(key => {
249
+ const value = changeFields[key];
250
+ if (typeof value === "undefined") {
251
+ delete doc[key];
252
+ }
253
+ else {
254
+ doc[key] = value;
255
+ }
256
+ });
257
+ };