mongodb-livedata-server 0.0.4 → 0.0.6

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 (93) hide show
  1. package/{livedata_server.ts → dist/livedata_server.d.ts} +1 -1
  2. package/dist/livedata_server.js +3 -1
  3. package/dist/meteor/binary-heap/max_heap.d.ts +31 -0
  4. package/dist/meteor/binary-heap/min_heap.d.ts +6 -0
  5. package/dist/meteor/binary-heap/min_max_heap.d.ts +11 -0
  6. package/dist/meteor/callback-hook/hook.d.ts +11 -0
  7. package/dist/meteor/ddp/crossbar.d.ts +15 -0
  8. package/dist/meteor/ddp/heartbeat.d.ts +19 -0
  9. package/dist/meteor/ddp/livedata_server.d.ts +141 -0
  10. package/dist/meteor/ddp/method-invocation.d.ts +25 -0
  11. package/dist/meteor/ddp/random-stream.d.ts +8 -0
  12. package/dist/meteor/ddp/session-collection-view.d.ts +27 -0
  13. package/dist/meteor/ddp/session-document-view.d.ts +8 -0
  14. package/dist/meteor/ddp/session.d.ts +69 -0
  15. package/dist/meteor/ddp/stream_server.d.ts +21 -0
  16. package/dist/meteor/ddp/subscription.d.ts +89 -0
  17. package/dist/meteor/ddp/utils.d.ts +8 -0
  18. package/dist/meteor/ddp/writefence.d.ts +20 -0
  19. package/dist/meteor/diff-sequence/diff.d.ts +13 -0
  20. package/dist/meteor/ejson/ejson.d.ts +82 -0
  21. package/dist/meteor/ejson/stringify.d.ts +2 -0
  22. package/dist/meteor/ejson/utils.d.ts +12 -0
  23. package/dist/meteor/id-map/id_map.d.ts +16 -0
  24. package/dist/meteor/mongo/caching_change_observer.d.ts +16 -0
  25. package/dist/meteor/mongo/doc_fetcher.d.ts +7 -0
  26. package/dist/meteor/mongo/geojson_utils.d.ts +3 -0
  27. package/dist/meteor/mongo/live_connection.d.ts +27 -0
  28. package/dist/meteor/mongo/live_cursor.d.ts +25 -0
  29. package/dist/meteor/mongo/minimongo_common.d.ts +84 -0
  30. package/dist/meteor/mongo/minimongo_matcher.d.ts +22 -0
  31. package/dist/meteor/mongo/minimongo_sorter.d.ts +16 -0
  32. package/dist/meteor/mongo/observe_driver_utils.d.ts +9 -0
  33. package/dist/meteor/mongo/observe_multiplexer.d.ts +36 -0
  34. package/dist/meteor/mongo/oplog-observe-driver.d.ts +67 -0
  35. package/dist/meteor/mongo/oplog_tailing.d.ts +35 -0
  36. package/dist/meteor/mongo/oplog_v2_converter.d.ts +1 -0
  37. package/dist/meteor/mongo/polling_observe_driver.d.ts +30 -0
  38. package/dist/meteor/mongo/synchronous-cursor.d.ts +17 -0
  39. package/dist/meteor/mongo/synchronous-queue.d.ts +14 -0
  40. package/dist/meteor/ordered-dict/ordered_dict.d.ts +31 -0
  41. package/dist/meteor/random/AbstractRandomGenerator.d.ts +42 -0
  42. package/dist/meteor/random/AleaRandomGenerator.d.ts +13 -0
  43. package/dist/meteor/random/NodeRandomGenerator.d.ts +16 -0
  44. package/dist/meteor/random/createAleaGenerator.d.ts +2 -0
  45. package/dist/meteor/random/createRandom.d.ts +1 -0
  46. package/dist/meteor/random/main.d.ts +1 -0
  47. package/package.json +2 -2
  48. package/meteor/LICENSE +0 -28
  49. package/meteor/binary-heap/max_heap.ts +0 -225
  50. package/meteor/binary-heap/min_heap.ts +0 -15
  51. package/meteor/binary-heap/min_max_heap.ts +0 -53
  52. package/meteor/callback-hook/hook.ts +0 -85
  53. package/meteor/ddp/crossbar.ts +0 -148
  54. package/meteor/ddp/heartbeat.ts +0 -97
  55. package/meteor/ddp/livedata_server.ts +0 -474
  56. package/meteor/ddp/method-invocation.ts +0 -86
  57. package/meteor/ddp/random-stream.ts +0 -102
  58. package/meteor/ddp/session-collection-view.ts +0 -119
  59. package/meteor/ddp/session-document-view.ts +0 -92
  60. package/meteor/ddp/session.ts +0 -708
  61. package/meteor/ddp/stream_server.ts +0 -204
  62. package/meteor/ddp/subscription.ts +0 -392
  63. package/meteor/ddp/utils.ts +0 -119
  64. package/meteor/ddp/writefence.ts +0 -130
  65. package/meteor/diff-sequence/diff.ts +0 -295
  66. package/meteor/ejson/ejson.ts +0 -601
  67. package/meteor/ejson/stringify.ts +0 -122
  68. package/meteor/ejson/utils.ts +0 -38
  69. package/meteor/id-map/id_map.ts +0 -84
  70. package/meteor/mongo/caching_change_observer.ts +0 -120
  71. package/meteor/mongo/doc_fetcher.ts +0 -52
  72. package/meteor/mongo/geojson_utils.ts +0 -42
  73. package/meteor/mongo/live_connection.ts +0 -302
  74. package/meteor/mongo/live_cursor.ts +0 -79
  75. package/meteor/mongo/minimongo_common.ts +0 -2440
  76. package/meteor/mongo/minimongo_matcher.ts +0 -275
  77. package/meteor/mongo/minimongo_sorter.ts +0 -331
  78. package/meteor/mongo/observe_driver_utils.ts +0 -79
  79. package/meteor/mongo/observe_multiplexer.ts +0 -256
  80. package/meteor/mongo/oplog-observe-driver.ts +0 -1049
  81. package/meteor/mongo/oplog_tailing.ts +0 -414
  82. package/meteor/mongo/oplog_v2_converter.ts +0 -124
  83. package/meteor/mongo/polling_observe_driver.ts +0 -247
  84. package/meteor/mongo/synchronous-cursor.ts +0 -293
  85. package/meteor/mongo/synchronous-queue.ts +0 -119
  86. package/meteor/ordered-dict/ordered_dict.ts +0 -229
  87. package/meteor/random/AbstractRandomGenerator.ts +0 -99
  88. package/meteor/random/AleaRandomGenerator.ts +0 -96
  89. package/meteor/random/NodeRandomGenerator.ts +0 -37
  90. package/meteor/random/createAleaGenerator.ts +0 -31
  91. package/meteor/random/createRandom.ts +0 -19
  92. package/meteor/random/main.ts +0 -8
  93. package/tsconfig.json +0 -10
@@ -1,204 +0,0 @@
1
- import { Server } from "http";
2
- import deflate from "permessage-deflate";
3
- import sockjs from "sockjs";
4
- import url from "url";
5
- import { DDPSession } from "./session";
6
-
7
- export interface StreamServerSocket extends sockjs.Connection {
8
- setWebsocketTimeout: Function;
9
- _session?: any;
10
- _meteorSession?: DDPSession;
11
- send: Function;
12
- }
13
- // By default, we use the permessage-deflate extension with default
14
- // configuration.
15
-
16
- export class StreamServer {
17
- private registration_callbacks = [];
18
- private open_sockets: StreamServerSocket[] = [];
19
-
20
- // Because we are installing directly onto WebApp.httpServer instead of using
21
- // WebApp.app, we have to process the path prefix ourselves.
22
-
23
- private prefix = '/sockjs';
24
- private server: sockjs.Server;
25
-
26
- constructor(private httpServer: Server) {
27
- //RoutePolicy.declare(this.prefix + '/', 'network');
28
- // set up sockjs
29
- const serverOptions = {
30
- prefix: this.prefix,
31
- log: function () { },
32
- // this is the default, but we code it explicitly because we depend
33
- // on it in stream_client:HEARTBEAT_TIMEOUT
34
- heartbeat_delay: 45000,
35
- // The default disconnect_delay is 5 seconds, but if the server ends up CPU
36
- // bound for that much time, SockJS might not notice that the user has
37
- // reconnected because the timer (of disconnect_delay ms) can fire before
38
- // SockJS processes the new connection. Eventually we'll fix this by not
39
- // combining CPU-heavy processing with SockJS termination (eg a proxy which
40
- // converts to Unix sockets) but for now, raise the delay.
41
- disconnect_delay: 60 * 1000,
42
- // Set the USE_JSESSIONID environment variable to enable setting the
43
- // JSESSIONID cookie. This is useful for setting up proxies with
44
- // session affinity.
45
- jsessionid: !!process.env.USE_JSESSIONID,
46
-
47
- websocket: true,
48
- faye_server_options: null
49
- };
50
-
51
- // If you know your server environment (eg, proxies) will prevent websockets
52
- // from ever working, set $DISABLE_WEBSOCKETS and SockJS clients (ie,
53
- // browsers) will not waste time attempting to use them.
54
- // (Your server will still have a /websocket endpoint.)
55
- if (process.env.DISABLE_WEBSOCKETS) {
56
- serverOptions.websocket = false;
57
- } else {
58
- serverOptions.faye_server_options = {
59
- extensions: [deflate.configure({})]
60
- };
61
- }
62
-
63
- this.server = sockjs.createServer(serverOptions);
64
-
65
- // Install the sockjs handlers, but we want to keep around our own particular
66
- // request handler that adjusts idle timeouts while we have an outstanding
67
- // request. This compensates for the fact that sockjs removes all listeners
68
- // for "request" to add its own.
69
- httpServer.removeListener(
70
- 'request', _timeoutAdjustmentRequestCallback);
71
- this.server.installHandlers(httpServer);
72
- httpServer.addListener(
73
- 'request', _timeoutAdjustmentRequestCallback);
74
-
75
- // Support the /websocket endpoint
76
- this._redirectWebsocketEndpoint();
77
-
78
- this.server.on('connection', (socket: StreamServerSocket) => {
79
- // sockjs sometimes passes us null instead of a socket object
80
- // so we need to guard against that. see:
81
- // https://github.com/sockjs/sockjs-node/issues/121
82
- // https://github.com/meteor/meteor/issues/10468
83
- if (!socket) return;
84
-
85
- // We want to make sure that if a client connects to us and does the initial
86
- // Websocket handshake but never gets to the DDP handshake, that we
87
- // eventually kill the socket. Once the DDP handshake happens, DDP
88
- // heartbeating will work. And before the Websocket handshake, the timeouts
89
- // we set at the server level in webapp_server.js will work. But
90
- // faye-websocket calls setTimeout(0) on any socket it takes over, so there
91
- // is an "in between" state where this doesn't happen. We work around this
92
- // by explicitly setting the socket timeout to a relatively large time here,
93
- // and setting it back to zero when we set up the heartbeat in
94
- // livedata_server.js.
95
- socket.setWebsocketTimeout = function (timeout) {
96
- if ((socket.protocol === 'websocket' ||
97
- socket.protocol === 'websocket-raw')
98
- && socket._session.recv) {
99
- socket._session.recv.connection.setTimeout(timeout);
100
- }
101
- };
102
- socket.setWebsocketTimeout(45 * 1000);
103
-
104
- socket.send = (data) => {
105
- socket.write(data);
106
- };
107
- socket.on('close', () => {
108
- this.open_sockets = this.open_sockets.filter(s => s !== socket);
109
- });
110
- this.open_sockets.push(socket);
111
-
112
- // only to send a message after connection on tests, useful for
113
- // socket-stream-client/server-tests.js
114
- if (process.env.TEST_METADATA && process.env.TEST_METADATA !== "{}") {
115
- socket.send(JSON.stringify({ testMessageOnConnect: true }));
116
- }
117
-
118
- // call all our callbacks when we get a new socket. they will do the
119
- // work of setting up handlers and such for specific messages.
120
- for (const callback of this.registration_callbacks) {
121
- callback(socket);
122
- }
123
- });
124
-
125
- };
126
-
127
- // call my callback when a new socket connects.
128
- // also call it for all current connections.
129
- register(callback: (socket: StreamServerSocket) => void) {
130
- var self = this;
131
- self.registration_callbacks.push(callback);
132
- for (const socket of self.all_sockets()) {
133
- callback(socket);
134
- }
135
- }
136
-
137
- // get a list of all sockets
138
- all_sockets() {
139
- return Object.values(this.open_sockets);
140
- }
141
-
142
- // Redirect /websocket to /sockjs/websocket in order to not expose
143
- // sockjs to clients that want to use raw websockets
144
- _redirectWebsocketEndpoint() {
145
- var self = this;
146
- // Unfortunately we can't use a connect middleware here since
147
- // sockjs installs itself prior to all existing listeners
148
- // (meaning prior to any connect middlewares) so we need to take
149
- // an approach similar to overshadowListeners in
150
- // https://github.com/sockjs/sockjs-node/blob/cf820c55af6a9953e16558555a31decea554f70e/src/utils.coffee
151
- ['request', 'upgrade'].forEach((event) => {
152
- var oldHttpServerListeners = this.httpServer.listeners(event).slice(0);
153
- this.httpServer.removeAllListeners(event);
154
-
155
- // request and upgrade have different arguments passed but
156
- // we only care about the first one which is always request
157
- var newListener = function (request /*, moreArguments */) {
158
- // Store arguments for use within the closure below
159
- var args = arguments;
160
-
161
- // Rewrite /websocket and /websocket/ urls to /sockjs/websocket while
162
- // preserving query string.
163
- var parsedUrl = url.parse(request.url);
164
- if (parsedUrl.pathname === '/websocket' ||
165
- parsedUrl.pathname === '/websocket/') {
166
- parsedUrl.pathname = self.prefix + '/websocket';
167
- request.url = url.format(parsedUrl);
168
- }
169
- for (const oldListener of oldHttpServerListeners) {
170
- oldListener.apply(this.httpServer, args);
171
- }
172
- };
173
- this.httpServer.addListener(event, newListener);
174
- });
175
- }
176
- }
177
-
178
-
179
- const SHORT_SOCKET_TIMEOUT = 5 * 1000;
180
- const LONG_SOCKET_TIMEOUT = 120 * 1000;
181
-
182
- // When we have a request pending, we want the socket timeout to be long, to
183
- // give ourselves a while to serve it, and to allow sockjs long polls to
184
- // complete. On the other hand, we want to close idle sockets relatively
185
- // quickly, so that we can shut down relatively promptly but cleanly, without
186
- // cutting off anyone's response.
187
- function _timeoutAdjustmentRequestCallback(req, res) {
188
- // this is really just req.socket.setTimeout(LONG_SOCKET_TIMEOUT);
189
- req.setTimeout(LONG_SOCKET_TIMEOUT);
190
- // Insert our new finish listener to run BEFORE the existing one which removes
191
- // the response from the socket.
192
- var finishListeners = res.listeners('finish');
193
- // XXX Apparently in Node 0.12 this event was called 'prefinish'.
194
- // https://github.com/joyent/node/commit/7c9b6070
195
- // But it has switched back to 'finish' in Node v4:
196
- // https://github.com/nodejs/node/pull/1411
197
- res.removeAllListeners('finish');
198
- res.on('finish', function () {
199
- res.setTimeout(SHORT_SOCKET_TIMEOUT);
200
- });
201
- for (const l of finishListeners) {
202
- res.on('finish', l);
203
- }
204
- };
@@ -1,392 +0,0 @@
1
- // Ctor for a sub handle: the input to each publish function
2
-
3
- import { clone } from "../ejson/ejson";
4
- import { LiveCursor } from "../mongo/live_cursor";
5
- import { Random } from "../random/main";
6
- import { DDP, maybeAuditArgumentChecks } from "./livedata_server";
7
- import { DDPSession, SessionConnectionHandle } from "./session";
8
-
9
- type SubscriptionHandle = `N${string}` | `U${string}`;
10
-
11
- // Instance name is this because it's usually referred to as this inside a
12
- // publish
13
- /**
14
- * @summary The server's side of a subscription
15
- * @class Subscription
16
- * @instanceName this
17
- * @showInstanceName true
18
- */
19
- export class Subscription {
20
- public connection: SessionConnectionHandle;
21
- private _subscriptionHandle: SubscriptionHandle;
22
-
23
- // Has _deactivate been called?
24
- private _deactivated = false;
25
-
26
- // Stop callbacks to g/c this sub. called w/ zero arguments.
27
- private _stopCallbacks: (() => void)[] = [];
28
-
29
- // The set of (collection, documentid) that this subscription has
30
- // an opinion about.
31
- private _documents = new Map();
32
-
33
- // Remember if we are ready.
34
- private _ready = false;
35
-
36
- public userId: string | null;
37
-
38
- // For now, the id filter is going to default to
39
- // the to/from DDP methods on MongoID, to
40
- // specifically deal with mongo/minimongo ObjectIds.
41
-
42
- // Later, you will be able to make this be "raw"
43
- // if you want to publish a collection that you know
44
- // just has strings for keys and no funny business, to
45
- // a DDP consumer that isn't minimongo.
46
- private _idFilter = {
47
- idStringify: id => id/*MongoID.idStringify*/,
48
- idParse: id => id/*MongoID.idParse*/
49
- }
50
-
51
- constructor (
52
- public _session: DDPSession,
53
- private _handler: any,
54
- private _subscriptionId: string,
55
- private _params: any[] = [],
56
- private _name?: string)
57
- {
58
-
59
- /**
60
- * @summary Access inside the publish function. The incoming [connection](#meteor_onconnection) for this subscription.
61
- * @locus Server
62
- * @name connection
63
- * @memberOf Subscription
64
- * @instance
65
- */
66
- this.connection = _session.connectionHandle; // public API object
67
-
68
- // Only named subscriptions have IDs, but we need some sort of string
69
- // internally to keep track of all subscriptions inside
70
- // SessionDocumentViews. We use this subscriptionHandle for that.
71
- if (this._subscriptionId) {
72
- this._subscriptionHandle = `N${this._subscriptionId}`;
73
- } else {
74
- this._subscriptionHandle = `U${Random.id()}`;
75
- }
76
-
77
-
78
- // Part of the public API: the user of this sub.
79
-
80
- /**
81
- * @summary Access inside the publish function. The id of the logged-in user, or `null` if no user is logged in.
82
- * @locus Server
83
- * @memberOf Subscription
84
- * @name userId
85
- * @instance
86
- */
87
- this.userId = this._session.userId;
88
-
89
- };
90
-
91
- _runHandler() {
92
- // XXX should we unblock() here? Either before running the publish
93
- // function, or before running _publishCursor.
94
- //
95
- // Right now, each publish function blocks all future publishes and
96
- // methods waiting on data from Mongo (or whatever else the function
97
- // blocks on). This probably slows page load in common cases.
98
-
99
- let resultOrThenable = null;
100
- const oldInvocation = DDP._CurrentPublicationInvocation;
101
- try {
102
- DDP._CurrentPublicationInvocation = this;
103
- resultOrThenable = maybeAuditArgumentChecks(
104
- this._handler,
105
- this,
106
- clone(this._params),
107
- // It's OK that this would look weird for universal subscriptions,
108
- // because they have no arguments so there can never be an
109
- // audit-argument-checks failure.
110
- "publisher '" + this._name + "'"
111
- )
112
- } catch (e) {
113
- this.error(e);
114
- return;
115
- } finally {
116
- DDP._CurrentPublicationInvocation = oldInvocation;
117
- }
118
-
119
- // Did the handler call this.error or this.stop?
120
- if (this._isDeactivated()) return;
121
-
122
- // Both conventional and async publish handler functions are supported.
123
- // If an object is returned with a then() function, it is either a promise
124
- // or thenable and will be resolved asynchronously.
125
- const isThenable =
126
- resultOrThenable && typeof resultOrThenable.then === 'function';
127
- if (isThenable) {
128
- Promise.resolve(resultOrThenable).then(
129
- (...args) => this._publishHandlerResult.bind(this)(...args),
130
- e => this.error(e)
131
- );
132
- } else {
133
- this._publishHandlerResult(resultOrThenable);
134
- }
135
- }
136
-
137
- _publishHandlerResult(res) {
138
- // SPECIAL CASE: Instead of writing their own callbacks that invoke
139
- // this.added/changed/ready/etc, the user can just return a collection
140
- // cursor or array of cursors from the publish function; we call their
141
- // _publishCursor method which starts observing the cursor and publishes the
142
- // results. Note that _publishCursor does NOT call ready().
143
- //
144
- // XXX This uses an undocumented interface which only the Mongo cursor
145
- // interface publishes. Should we make this interface public and encourage
146
- // users to implement it themselves? Arguably, it's unnecessary; users can
147
- // already write their own functions like
148
- // var publishMyReactiveThingy = function (name, handler) {
149
- // Meteor.publish(name, function () {
150
- // var reactiveThingy = handler();
151
- // reactiveThingy.publishMe();
152
- // });
153
- // };
154
-
155
- var self = this;
156
- var isCursor = function (c: any): c is LiveCursor<any> {
157
- return c && c._publishCursor;
158
- };
159
- if (isCursor(res)) {
160
- try {
161
- res._publishCursor(self);
162
- } catch (e) {
163
- self.error(e);
164
- return;
165
- }
166
- // _publishCursor only returns after the initial added callbacks have run.
167
- // mark subscription as ready.
168
- self.ready();
169
- } else if (Array.isArray(res)) {
170
- // Check all the elements are cursors
171
- if (!res.every(isCursor)) {
172
- self.error(new Error("Publish function returned an array of non-Cursors"));
173
- return;
174
- }
175
- // Find duplicate collection names
176
- // XXX we should support overlapping cursors, but that would require the
177
- // merge box to allow overlap within a subscription
178
- var collectionNames = {};
179
- for (var i = 0; i < res.length; ++i) {
180
- var collectionName = res[i].cursorDescription.collectionName;
181
- if (collectionNames.hasOwnProperty(collectionName)) {
182
- self.error(new Error(
183
- "Publish function returned multiple cursors for collection " +
184
- collectionName));
185
- return;
186
- }
187
- collectionNames[collectionName] = true;
188
- };
189
-
190
- try {
191
- for (const cur of res) {
192
- cur._publishCursor(self);
193
- }
194
- } catch (e) {
195
- self.error(e);
196
- return;
197
- }
198
- self.ready();
199
- } else if (res) {
200
- // Truthy values other than cursors or arrays are probably a
201
- // user mistake (possible returning a Mongo document via, say,
202
- // `coll.findOne()`).
203
- self.error(new Error("Publish function can only return a Cursor or "
204
- + "an array of Cursors"));
205
- }
206
- }
207
-
208
- // This calls all stop callbacks and prevents the handler from updating any
209
- // SessionCollectionViews further. It's used when the user unsubscribes or
210
- // disconnects, as well as during setUserId re-runs. It does *NOT* send
211
- // removed messages for the published objects; if that is necessary, call
212
- // _removeAllDocuments first.
213
- _deactivate() {
214
- var self = this;
215
- if (self._deactivated)
216
- return;
217
- self._deactivated = true;
218
- self._callStopCallbacks();
219
- /*Package['facts-base'] && Package['facts-base'].Facts.incrementServerFact(
220
- "livedata", "subscriptions", -1);*/
221
- }
222
-
223
- _callStopCallbacks() {
224
- var self = this;
225
- // Tell listeners, so they can clean up
226
- var callbacks = self._stopCallbacks;
227
- self._stopCallbacks = [];
228
- for (const callback of callbacks) {
229
- callback();
230
- }
231
- }
232
-
233
- // Send remove messages for every document.
234
- _removeAllDocuments() {
235
- var self = this;
236
- self._documents.forEach(function (collectionDocs, collectionName) {
237
- collectionDocs.forEach(function (strId) {
238
- self.removed(collectionName, self._idFilter.idParse(strId));
239
- });
240
- });
241
- }
242
-
243
- // Returns a new Subscription for the same session with the same
244
- // initial creation parameters. This isn't a clone: it doesn't have
245
- // the same _documents cache, stopped state or callbacks; may have a
246
- // different _subscriptionHandle, and gets its userId from the
247
- // session, not from this object.
248
- _recreate() {
249
- var self = this;
250
- return new Subscription(
251
- self._session, self._handler, self._subscriptionId, self._params,
252
- self._name);
253
- }
254
-
255
- /**
256
- * @summary Call inside the publish function. Stops this client's subscription, triggering a call on the client to the `onStop` callback passed to [`Meteor.subscribe`](#meteor_subscribe), if any. If `error` is not a [`Meteor.Error`](#meteor_error), it will be [sanitized](#meteor_error).
257
- * @locus Server
258
- * @param {Error} error The error to pass to the client.
259
- * @instance
260
- * @memberOf Subscription
261
- */
262
- error(error: Error) {
263
- var self = this;
264
- if (self._isDeactivated())
265
- return;
266
- self._session._stopSubscription(self._subscriptionId, error);
267
- }
268
-
269
- // Note that while our DDP client will notice that you've called stop() on the
270
- // server (and clean up its _subscriptions table) we don't actually provide a
271
- // mechanism for an app to notice this (the subscribe onError callback only
272
- // triggers if there is an error).
273
-
274
- /**
275
- * @summary Call inside the publish function. Stops this client's subscription and invokes the client's `onStop` callback with no error.
276
- * @locus Server
277
- * @instance
278
- * @memberOf Subscription
279
- */
280
- stop() {
281
- var self = this;
282
- if (self._isDeactivated())
283
- return;
284
- self._session._stopSubscription(self._subscriptionId);
285
- }
286
-
287
- /**
288
- * @summary Call inside the publish function. Registers a callback function to run when the subscription is stopped.
289
- * @locus Server
290
- * @memberOf Subscription
291
- * @instance
292
- * @param {Function} func The callback function
293
- */
294
- onStop(func: () => void) {
295
- var self = this;
296
- if (self._isDeactivated())
297
- func();
298
- else
299
- self._stopCallbacks.push(func);
300
- }
301
-
302
- // This returns true if the sub has been deactivated, *OR* if the session was
303
- // destroyed but the deferred call to _deactivateAllSubscriptions hasn't
304
- // happened yet.
305
- _isDeactivated() {
306
- var self = this;
307
- return self._deactivated || self._session.inQueue === null;
308
- }
309
-
310
- /**
311
- * @summary Call inside the publish function. Informs the subscriber that a document has been added to the record set.
312
- * @locus Server
313
- * @memberOf Subscription
314
- * @instance
315
- * @param {String} collection The name of the collection that contains the new document.
316
- * @param {String} id The new document's ID.
317
- * @param {Object} fields The fields in the new document. If `_id` is present it is ignored.
318
- */
319
- added(collectionName: string, id: string, fields: Record<string, any>) {
320
- if (this._isDeactivated())
321
- return;
322
- id = this._idFilter.idStringify(id);
323
-
324
- if (this._session.server.getPublicationStrategy(collectionName).doAccountingForCollection) {
325
- let ids = this._documents.get(collectionName);
326
- if (ids == null) {
327
- ids = new Set();
328
- this._documents.set(collectionName, ids);
329
- }
330
- ids.add(id);
331
- }
332
-
333
- this._session.added(this._subscriptionHandle, collectionName, id, fields);
334
- }
335
-
336
- /**
337
- * @summary Call inside the publish function. Informs the subscriber that a document in the record set has been modified.
338
- * @locus Server
339
- * @memberOf Subscription
340
- * @instance
341
- * @param {String} collection The name of the collection that contains the changed document.
342
- * @param {String} id The changed document's ID.
343
- * @param {Object} fields The fields in the document that have changed, together with their new values. If a field is not present in `fields` it was left unchanged; if it is present in `fields` and has a value of `undefined` it was removed from the document. If `_id` is present it is ignored.
344
- */
345
- changed(collectionName: string, id: string, fields: Record<string, any>) {
346
- if (this._isDeactivated())
347
- return;
348
- id = this._idFilter.idStringify(id);
349
- this._session.changed(this._subscriptionHandle, collectionName, id, fields);
350
- }
351
-
352
- /**
353
- * @summary Call inside the publish function. Informs the subscriber that a document has been removed from the record set.
354
- * @locus Server
355
- * @memberOf Subscription
356
- * @instance
357
- * @param {String} collection The name of the collection that the document has been removed from.
358
- * @param {String} id The ID of the document that has been removed.
359
- */
360
- removed(collectionName: string, id: string) {
361
- if (this._isDeactivated())
362
- return;
363
- id = this._idFilter.idStringify(id);
364
-
365
- if (this._session.server.getPublicationStrategy(collectionName).doAccountingForCollection) {
366
- // We don't bother to delete sets of things in a collection if the
367
- // collection is empty. It could break _removeAllDocuments.
368
- this._documents.get(collectionName).delete(id);
369
- }
370
-
371
- this._session.removed(this._subscriptionHandle, collectionName, id);
372
- }
373
-
374
- /**
375
- * @summary Call inside the publish function. Informs the subscriber that an initial, complete snapshot of the record set has been sent. This will trigger a call on the client to the `onReady` callback passed to [`Meteor.subscribe`](#meteor_subscribe), if any.
376
- * @locus Server
377
- * @memberOf Subscription
378
- * @instance
379
- */
380
- ready() {
381
- var self = this;
382
- if (self._isDeactivated())
383
- return;
384
- if (!self._subscriptionId)
385
- return; // Unnecessary but ignored for universal sub
386
- if (!self._ready) {
387
- self._session.sendReady([self._subscriptionId]);
388
- self._ready = true;
389
- }
390
- }
391
-
392
- }