mongodb-livedata-server 0.0.1

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 (94) hide show
  1. package/README.md +63 -0
  2. package/dist/livedata_server.js +9 -0
  3. package/dist/meteor/binary-heap/max_heap.js +186 -0
  4. package/dist/meteor/binary-heap/min_heap.js +17 -0
  5. package/dist/meteor/binary-heap/min_max_heap.js +48 -0
  6. package/dist/meteor/callback-hook/hook.js +78 -0
  7. package/dist/meteor/ddp/crossbar.js +136 -0
  8. package/dist/meteor/ddp/heartbeat.js +77 -0
  9. package/dist/meteor/ddp/livedata_server.js +403 -0
  10. package/dist/meteor/ddp/method-invocation.js +72 -0
  11. package/dist/meteor/ddp/random-stream.js +100 -0
  12. package/dist/meteor/ddp/session-collection-view.js +106 -0
  13. package/dist/meteor/ddp/session-document-view.js +82 -0
  14. package/dist/meteor/ddp/session.js +570 -0
  15. package/dist/meteor/ddp/stream_server.js +181 -0
  16. package/dist/meteor/ddp/subscription.js +347 -0
  17. package/dist/meteor/ddp/utils.js +104 -0
  18. package/dist/meteor/ddp/writefence.js +111 -0
  19. package/dist/meteor/diff-sequence/diff.js +257 -0
  20. package/dist/meteor/ejson/ejson.js +569 -0
  21. package/dist/meteor/ejson/stringify.js +119 -0
  22. package/dist/meteor/ejson/utils.js +42 -0
  23. package/dist/meteor/id-map/id_map.js +92 -0
  24. package/dist/meteor/mongo/caching_change_observer.js +94 -0
  25. package/dist/meteor/mongo/doc_fetcher.js +53 -0
  26. package/dist/meteor/mongo/geojson_utils.js +41 -0
  27. package/dist/meteor/mongo/live_connection.js +264 -0
  28. package/dist/meteor/mongo/live_cursor.js +57 -0
  29. package/dist/meteor/mongo/minimongo_common.js +2002 -0
  30. package/dist/meteor/mongo/minimongo_matcher.js +217 -0
  31. package/dist/meteor/mongo/minimongo_sorter.js +268 -0
  32. package/dist/meteor/mongo/observe_driver_utils.js +73 -0
  33. package/dist/meteor/mongo/observe_multiplexer.js +228 -0
  34. package/dist/meteor/mongo/oplog-observe-driver.js +919 -0
  35. package/dist/meteor/mongo/oplog_tailing.js +352 -0
  36. package/dist/meteor/mongo/oplog_v2_converter.js +126 -0
  37. package/dist/meteor/mongo/polling_observe_driver.js +195 -0
  38. package/dist/meteor/mongo/synchronous-cursor.js +261 -0
  39. package/dist/meteor/mongo/synchronous-queue.js +110 -0
  40. package/dist/meteor/ordered-dict/ordered_dict.js +198 -0
  41. package/dist/meteor/random/AbstractRandomGenerator.js +92 -0
  42. package/dist/meteor/random/AleaRandomGenerator.js +90 -0
  43. package/dist/meteor/random/NodeRandomGenerator.js +42 -0
  44. package/dist/meteor/random/createAleaGenerator.js +32 -0
  45. package/dist/meteor/random/createRandom.js +22 -0
  46. package/dist/meteor/random/main.js +12 -0
  47. package/livedata_server.ts +3 -0
  48. package/meteor/LICENSE +28 -0
  49. package/meteor/binary-heap/max_heap.ts +225 -0
  50. package/meteor/binary-heap/min_heap.ts +15 -0
  51. package/meteor/binary-heap/min_max_heap.ts +53 -0
  52. package/meteor/callback-hook/hook.ts +85 -0
  53. package/meteor/ddp/crossbar.ts +148 -0
  54. package/meteor/ddp/heartbeat.ts +97 -0
  55. package/meteor/ddp/livedata_server.ts +473 -0
  56. package/meteor/ddp/method-invocation.ts +86 -0
  57. package/meteor/ddp/random-stream.ts +102 -0
  58. package/meteor/ddp/session-collection-view.ts +119 -0
  59. package/meteor/ddp/session-document-view.ts +92 -0
  60. package/meteor/ddp/session.ts +708 -0
  61. package/meteor/ddp/stream_server.ts +204 -0
  62. package/meteor/ddp/subscription.ts +392 -0
  63. package/meteor/ddp/utils.ts +119 -0
  64. package/meteor/ddp/writefence.ts +130 -0
  65. package/meteor/diff-sequence/diff.ts +295 -0
  66. package/meteor/ejson/ejson.ts +601 -0
  67. package/meteor/ejson/stringify.ts +122 -0
  68. package/meteor/ejson/utils.ts +38 -0
  69. package/meteor/id-map/id_map.ts +84 -0
  70. package/meteor/mongo/caching_change_observer.ts +120 -0
  71. package/meteor/mongo/doc_fetcher.ts +52 -0
  72. package/meteor/mongo/geojson_utils.ts +42 -0
  73. package/meteor/mongo/live_connection.ts +302 -0
  74. package/meteor/mongo/live_cursor.ts +79 -0
  75. package/meteor/mongo/minimongo_common.ts +2440 -0
  76. package/meteor/mongo/minimongo_matcher.ts +275 -0
  77. package/meteor/mongo/minimongo_sorter.ts +331 -0
  78. package/meteor/mongo/observe_driver_utils.ts +79 -0
  79. package/meteor/mongo/observe_multiplexer.ts +256 -0
  80. package/meteor/mongo/oplog-observe-driver.ts +1049 -0
  81. package/meteor/mongo/oplog_tailing.ts +414 -0
  82. package/meteor/mongo/oplog_v2_converter.ts +124 -0
  83. package/meteor/mongo/polling_observe_driver.ts +247 -0
  84. package/meteor/mongo/synchronous-cursor.ts +293 -0
  85. package/meteor/mongo/synchronous-queue.ts +119 -0
  86. package/meteor/ordered-dict/ordered_dict.ts +229 -0
  87. package/meteor/random/AbstractRandomGenerator.ts +99 -0
  88. package/meteor/random/AleaRandomGenerator.ts +96 -0
  89. package/meteor/random/NodeRandomGenerator.ts +37 -0
  90. package/meteor/random/createAleaGenerator.ts +31 -0
  91. package/meteor/random/createRandom.ts +19 -0
  92. package/meteor/random/main.ts +8 -0
  93. package/package.json +30 -0
  94. package/tsconfig.json +10 -0
@@ -0,0 +1,256 @@
1
+ import { clone } from "../ejson/ejson";
2
+ import { _CachingChangeObserver } from "./caching_change_observer";
3
+ import { _SynchronousQueue } from "./synchronous-queue";
4
+
5
+ export class ObserveMultiplexer {
6
+ private _ordered: boolean;
7
+ private _onStop: Function;
8
+ private _queue: _SynchronousQueue;
9
+ private _handles: Record<number, ObserveHandle>;
10
+ private _readyFuture: { promise?: Promise<void>, resolve?: Function, reject?: Function, isResolved: boolean } = { isResolved: false };
11
+ private _cache: any;
12
+ private _addHandleTasksScheduledButNotPerformed: number;
13
+
14
+ public added: (id: string, fields: Record<string, any>) => void;
15
+ public changed: (id: string, fields: Record<string, any>) => void;
16
+ public removed: (id: string) => void;
17
+
18
+ constructor(options) {
19
+ var self = this;
20
+
21
+ if (!options || !options.hasOwnProperty('ordered'))
22
+ throw Error("must specify ordered");
23
+
24
+ self._ordered = options.ordered;
25
+ self._onStop = options.onStop || function () { };
26
+ self._queue = new _SynchronousQueue();
27
+ self._handles = {};
28
+ self._readyFuture.promise = new Promise<void>((resolve, reject) => {
29
+ self._readyFuture.resolve = resolve;
30
+ self._readyFuture.reject = reject;
31
+ });
32
+ self._cache = new _CachingChangeObserver({ ordered: options.ordered });
33
+ // Number of addHandleAndSendInitialAdds tasks scheduled but not yet
34
+ // running. removeHandle uses this to know if it's time to call the onStop
35
+ // callback.
36
+ self._addHandleTasksScheduledButNotPerformed = 0;
37
+
38
+ for (const callbackName of self.callbackNames()) {
39
+ self[callbackName] = function (/* ... */) {
40
+ self._applyCallback(callbackName, Array.from(arguments));
41
+ };
42
+ }
43
+ }
44
+
45
+ async addHandleAndSendInitialAdds(handle: ObserveHandle) {
46
+ var self = this;
47
+
48
+ // Check this before calling runTask (even though runTask does the same
49
+ // check) so that we don't leak an ObserveMultiplexer on error by
50
+ // incrementing _addHandleTasksScheduledButNotPerformed and never
51
+ // decrementing it.
52
+ //if (!self._queue.safeToRunTask())
53
+ // throw new Error("Can't call observeChanges from an observe callback on the same query");
54
+ ++self._addHandleTasksScheduledButNotPerformed;
55
+
56
+ await self._queue.runTask(async () => {
57
+ self._handles[handle._id] = handle;
58
+ // Send out whatever adds we have so far (whether or not we the
59
+ // multiplexer is ready).
60
+ self._sendAdds(handle);
61
+ --self._addHandleTasksScheduledButNotPerformed;
62
+ });
63
+ // *outside* the task, since otherwise we'd deadlock
64
+ await self._readyFuture.promise;
65
+ }
66
+
67
+ // Remove an observe handle. If it was the last observe handle, call the
68
+ // onStop callback; you cannot add any more observe handles after this.
69
+ //
70
+ // This is not synchronized with polls and handle additions: this means that
71
+ // you can safely call it from within an observe callback, but it also means
72
+ // that we have to be careful when we iterate over _handles.
73
+ removeHandle(id: number) {
74
+ var self = this;
75
+
76
+ // This should not be possible: you can only call removeHandle by having
77
+ // access to the ObserveHandle, which isn't returned to user code until the
78
+ // multiplex is ready.
79
+ if (!self._ready())
80
+ throw new Error("Can't remove handles until the multiplex is ready");
81
+
82
+ delete self._handles[id];
83
+
84
+ if (Object.keys(self._handles).length === 0 && self._addHandleTasksScheduledButNotPerformed === 0) {
85
+ self._stop();
86
+ }
87
+ }
88
+ _stop(options?) {
89
+ var self = this;
90
+ options = options || {};
91
+
92
+ // It shouldn't be possible for us to stop when all our handles still
93
+ // haven't been returned from observeChanges!
94
+ if (!self._ready() && !options.fromQueryError)
95
+ throw Error("surprising _stop: not ready");
96
+
97
+ // Call stop callback (which kills the underlying process which sends us
98
+ // callbacks and removes us from the connection's dictionary).
99
+ self._onStop();
100
+
101
+ // Cause future addHandleAndSendInitialAdds calls to throw (but the onStop
102
+ // callback should make our connection forget about us).
103
+ self._handles = null;
104
+ }
105
+
106
+ // Allows all addHandleAndSendInitialAdds calls to return, once all preceding
107
+ // adds have been processed. Does not block.
108
+ ready() {
109
+ var self = this;
110
+ self._queue.queueTask(async () => {
111
+ if (self._ready())
112
+ throw Error("can't make ObserveMultiplex ready twice!");
113
+ self._readyFuture.resolve();
114
+ self._readyFuture.isResolved = true;
115
+ });
116
+ }
117
+
118
+ // If trying to execute the query results in an error, call this. This is
119
+ // intended for permanent errors, not transient network errors that could be
120
+ // fixed. It should only be called before ready(), because if you called ready
121
+ // that meant that you managed to run the query once. It will stop this
122
+ // ObserveMultiplex and cause addHandleAndSendInitialAdds calls (and thus
123
+ // observeChanges calls) to throw the error.
124
+ queryError(err: Error) {
125
+ var self = this;
126
+ self._queue.runTask(async () => {
127
+ if (self._ready())
128
+ throw Error("can't claim query has an error after it worked!");
129
+ self._stop({ fromQueryError: true });
130
+ self._readyFuture.reject(err);
131
+ });
132
+ }
133
+
134
+ // Calls "cb" once the effects of all "ready", "addHandleAndSendInitialAdds"
135
+ // and observe callbacks which came before this call have been propagated to
136
+ // all handles. "ready" must have already been called on this multiplexer.
137
+ onFlush(cb) {
138
+ var self = this;
139
+ self._queue.queueTask(async () => {
140
+ if (!self._ready())
141
+ throw Error("only call onFlush on a multiplexer that will be ready");
142
+ cb();
143
+ });
144
+ }
145
+ callbackNames() {
146
+ var self = this;
147
+ if (self._ordered)
148
+ return ["addedBefore", "changed", "movedBefore", "removed"];
149
+ else
150
+ return ["added", "changed", "removed"];
151
+ }
152
+ _ready() {
153
+ return this._readyFuture.isResolved;
154
+ }
155
+ _applyCallback(callbackName: string, args) {
156
+ var self = this;
157
+ self._queue.queueTask(async () => {
158
+ // If we stopped in the meantime, do nothing.
159
+ if (!self._handles)
160
+ return;
161
+
162
+ // First, apply the change to the cache.
163
+ self._cache.applyChange[callbackName].apply(null, args);
164
+
165
+ // If we haven't finished the initial adds, then we should only be getting
166
+ // adds.
167
+ if (!self._ready() &&
168
+ (callbackName !== 'added' && callbackName !== 'addedBefore')) {
169
+ throw new Error("Got " + callbackName + " during initial adds");
170
+ }
171
+
172
+ // Now multiplex the callbacks out to all observe handles. It's OK if
173
+ // these calls yield; since we're inside a task, no other use of our queue
174
+ // can continue until these are done. (But we do have to be careful to not
175
+ // use a handle that got removed, because removeHandle does not use the
176
+ // queue; thus, we iterate over an array of keys that we control.)
177
+ for (const handleId of Object.keys(self._handles)) {
178
+ var handle = self._handles && self._handles[handleId];
179
+ if (!handle)
180
+ return;
181
+ var callback = handle['_' + callbackName];
182
+ // clone arguments so that callbacks can mutate their arguments
183
+ callback && callback.apply(null,
184
+ handle.nonMutatingCallbacks ? args : clone(args));
185
+ }
186
+ });
187
+ }
188
+
189
+ // Sends initial adds to a handle. It should only be called from within a task
190
+ // (the task that is processing the addHandleAndSendInitialAdds call). It
191
+ // synchronously invokes the handle's added or addedBefore; there's no need to
192
+ // flush the queue afterwards to ensure that the callbacks get out.
193
+ _sendAdds(handle: ObserveHandle) {
194
+ var self = this;
195
+ //if (self._queue.safeToRunTask())
196
+ // throw Error("_sendAdds may only be called from within a task!");
197
+ var add = self._ordered ? handle._addedBefore : handle._added;
198
+ if (!add)
199
+ return;
200
+ // note: docs may be an _IdMap or an OrderedDict
201
+ self._cache.docs.forEach(function (doc, id) {
202
+ if (!self._handles.hasOwnProperty(handle._id))
203
+ throw Error("handle got removed before sending initial adds!");
204
+ const { _id, ...fields } = handle.nonMutatingCallbacks ? doc : clone(doc);
205
+ if (self._ordered)
206
+ add(id, fields, null); // we're going in order, so add at end
207
+ else
208
+ add(id, fields);
209
+ });
210
+ }
211
+ }
212
+
213
+
214
+ let nextObserveHandleId = 1;
215
+
216
+ // When the callbacks do not mutate the arguments, we can skip a lot of data clones
217
+ export class ObserveHandle {
218
+
219
+ public _id: number;
220
+ public _addedBefore: Function;
221
+ public _movedBefore: Function;
222
+ public _added: Function;
223
+ public _changed: Function;
224
+ public _removed: Function;
225
+
226
+ private _stopped: boolean;
227
+
228
+ constructor(private _multiplexer: ObserveMultiplexer, callbacks: Record<string, Function>, public nonMutatingCallbacks = false) {
229
+ var self = this;
230
+ // The end user is only supposed to call stop(). The other fields are
231
+ // accessible to the multiplexer, though.
232
+ for (const name of _multiplexer.callbackNames()) {
233
+ if (callbacks[name]) {
234
+ self['_' + name] = callbacks[name];
235
+ } else if (name === "addedBefore" && callbacks.added) {
236
+ // Special case: if you specify "added" and "movedBefore", you get an
237
+ // ordered observe where for some reason you don't get ordering data on
238
+ // the adds. I dunno, we wrote tests for it, there must have been a
239
+ // reason.
240
+ self._addedBefore = function (id: string, fields: Record<string, any>, before) {
241
+ callbacks.added(id, fields);
242
+ };
243
+ }
244
+ }
245
+ self._stopped = false;
246
+ self._id = nextObserveHandleId++;
247
+ }
248
+
249
+ stop() {
250
+ var self = this;
251
+ if (self._stopped)
252
+ return;
253
+ self._stopped = true;
254
+ self._multiplexer.removeHandle(self._id);
255
+ }
256
+ }