From d6f0fdfb35989462dcc66b607aa00579fba387f6 Mon Sep 17 00:00:00 2001 From: Sashko Stubailo Date: Wed, 8 Nov 2017 16:49:01 -0800 Subject: [PATCH] Get ClientStream off of LivedataTest --- packages/ddp-client/client/client.js | 5 +- .../ddp-client/client/stream_client_sockjs.js | 4 +- .../ddp-client/common/getClientStreamClass.js | 18 +++++++ .../ddp-client/common/livedata_connection.js | 54 ++----------------- packages/ddp-client/common/namespace.js | 51 +++++++++++++++++- packages/ddp-client/server/server.js | 6 +-- .../ddp-client/server/stream_client_nodejs.js | 2 +- packages/ddp-client/test/stream_tests.js | 8 ++- 8 files changed, 86 insertions(+), 62 deletions(-) create mode 100644 packages/ddp-client/common/getClientStreamClass.js diff --git a/packages/ddp-client/client/client.js b/packages/ddp-client/client/client.js index ae2cdef588..6552c07950 100644 --- a/packages/ddp-client/client/client.js +++ b/packages/ddp-client/client/client.js @@ -1,7 +1,8 @@ export { DDP, LivedataTest } from '../common/namespace'; -import './stream_client_sockjs'; -import '../common/livedata_connection'; +if (false) { + import './stream_client_sockjs'; +} // Initialize the default server connection and put it on Meteor.connection import './client_convenience'; diff --git a/packages/ddp-client/client/stream_client_sockjs.js b/packages/ddp-client/client/stream_client_sockjs.js index 3b97ab9b80..9738a0e0a0 100644 --- a/packages/ddp-client/client/stream_client_sockjs.js +++ b/packages/ddp-client/client/stream_client_sockjs.js @@ -7,7 +7,7 @@ import { DDP, LivedataTest } from '../common/namespace.js'; import { toSockjsUrl } from '../common/urlHelpers'; import StreamClientCommon from '../common/stream_client_common'; -class ClientStream extends StreamClientCommon { +export default class ClientStream extends StreamClientCommon { // @param url {String} URL to Meteor app // "http://subdomain.meteor.com/" or "/" or // "ddp+sockjs://foo-**.meteor.com/sockjs" @@ -202,5 +202,3 @@ class ClientStream extends StreamClientCommon { }, this.CONNECT_TIMEOUT); } } - -LivedataTest.ClientStream = ClientStream; diff --git a/packages/ddp-client/common/getClientStreamClass.js b/packages/ddp-client/common/getClientStreamClass.js new file mode 100644 index 0000000000..14f9b60a62 --- /dev/null +++ b/packages/ddp-client/common/getClientStreamClass.js @@ -0,0 +1,18 @@ +import { Meteor } from 'meteor/meteor'; + +// In the client and server entry points, we make sure the +// bundler loads the correct thing. Here, we just need to +// make sure that we require the right one. +export default function getClientStreamClass() { + // The static analyzer of the bundler specifically looks + // for direct calls to 'require', so it won't treat the + // below calls as a request to include that module. + const notRequire = require; + + if (Meteor.isClient) { + return notRequire('../client/stream_client_sockjs').default; + } else { + /* Meteor.isServer */ return notRequire('../server/stream_client_nodejs') + .default; + } +} diff --git a/packages/ddp-client/common/livedata_connection.js b/packages/ddp-client/common/livedata_connection.js index efa68a06d0..4b0033731a 100644 --- a/packages/ddp-client/common/livedata_connection.js +++ b/packages/ddp-client/common/livedata_connection.js @@ -6,13 +6,14 @@ import { EJSON } from 'meteor/ejson'; import { Random } from 'meteor/random'; import { Hook } from 'meteor/callback-hook'; import { MongoID } from 'meteor/mongo-id'; +import { DDP } from './namespace'; +import getClientStreamClass from './getClientStreamClass'; if (Meteor.isServer) { var Fiber = Npm.require('fibers'); var Future = Npm.require('fibers/future'); } -import { DDP, LivedataTest } from './namespace.js'; import MethodInvoker from './MethodInvoker'; class MongoIDMap extends IdMap { @@ -41,7 +42,7 @@ class MongoIDMap extends IdMap { // fails. We should have better usability in the latter case (while // still transparently reconnecting if it's just a transient failure // or the server migrating us). -class Connection { +export class Connection { constructor(url, options) { var self = this; options = _.extend( @@ -77,7 +78,7 @@ class Connection { if (typeof url === 'object') { self._stream = url; } else { - self._stream = new LivedataTest.ClientStream(url, { + self._stream = new (getClientStreamClass())(url, { retry: options.retry, headers: options.headers, _sockjsOptions: options._sockjsOptions, @@ -1698,50 +1699,3 @@ class Connection { } } } - -LivedataTest.Connection = Connection; - -// @param url {String} URL to Meteor app, -// e.g.: -// "subdomain.meteor.com", -// "http://subdomain.meteor.com", -// "/", -// "ddp+sockjs://ddp--****-foo.meteor.com/sockjs" - -/** - * @summary Connect to the server of a different Meteor application to subscribe to its document sets and invoke its remote methods. - * @locus Anywhere - * @param {String} url The URL of another Meteor application. - */ -DDP.connect = function(url, options) { - var ret = new Connection(url, options); - allConnections.push(ret); // hack. see below. - return ret; -}; - -DDP._reconnectHook = new Hook({ bindEnvironment: false }); - -/** - * @summary Register a function to call as the first step of - * reconnecting. This function can call methods which will be executed before - * any other outstanding methods. For example, this can be used to re-establish - * the appropriate authentication context on the connection. - * @locus Anywhere - * @param {Function} callback The function to call. It will be called with a - * single argument, the [connection object](#ddp_connect) that is reconnecting. - */ -DDP.onReconnect = function(callback) { - return DDP._reconnectHook.register(callback); -}; - -// Hack for `spiderable` package: a way to see if the page is done -// loading all the data it needs. -// -allConnections = []; -DDP._allSubscriptionsReady = function() { - return _.all(allConnections, function(conn) { - return _.all(conn._subscriptions, function(sub) { - return sub.ready; - }); - }); -}; diff --git a/packages/ddp-client/common/namespace.js b/packages/ddp-client/common/namespace.js index 45a659e2cd..a4a972a406 100644 --- a/packages/ddp-client/common/namespace.js +++ b/packages/ddp-client/common/namespace.js @@ -1,12 +1,16 @@ import { DDPCommon } from 'meteor/ddp-common'; import { Meteor } from 'meteor/meteor'; +import { Connection } from './livedata_connection'; + /** * @namespace DDP * @summary Namespace for DDP-related methods/classes. */ export const DDP = {}; -export const LivedataTest = {}; +export const LivedataTest = { + Connection +}; // This is private but it's used in a few places. accounts-base uses // it to get the current user. Meteor.setTimeout and friends clear @@ -36,3 +40,48 @@ DDP.randomStream = function(name) { var scope = DDP._CurrentMethodInvocation.get(); return DDPCommon.RandomStream.get(scope, name); }; + +// @param url {String} URL to Meteor app, +// e.g.: +// "subdomain.meteor.com", +// "http://subdomain.meteor.com", +// "/", +// "ddp+sockjs://ddp--****-foo.meteor.com/sockjs" + +/** + * @summary Connect to the server of a different Meteor application to subscribe to its document sets and invoke its remote methods. + * @locus Anywhere + * @param {String} url The URL of another Meteor application. + */ +DDP.connect = function(url, options) { + var ret = new Connection(url, options); + allConnections.push(ret); // hack. see below. + return ret; +}; + +DDP._reconnectHook = new Hook({ bindEnvironment: false }); + +/** + * @summary Register a function to call as the first step of + * reconnecting. This function can call methods which will be executed before + * any other outstanding methods. For example, this can be used to re-establish + * the appropriate authentication context on the connection. + * @locus Anywhere + * @param {Function} callback The function to call. It will be called with a + * single argument, the [connection object](#ddp_connect) that is reconnecting. + */ +DDP.onReconnect = function(callback) { + return DDP._reconnectHook.register(callback); +}; + +// Hack for `spiderable` package: a way to see if the page is done +// loading all the data it needs. +// +allConnections = []; +DDP._allSubscriptionsReady = function() { + return _.all(allConnections, function(conn) { + return _.all(conn._subscriptions, function(sub) { + return sub.ready; + }); + }); +}; diff --git a/packages/ddp-client/server/server.js b/packages/ddp-client/server/server.js index 2f98545fab..dc3cf0bc63 100644 --- a/packages/ddp-client/server/server.js +++ b/packages/ddp-client/server/server.js @@ -1,5 +1,5 @@ export { DDP, LivedataTest } from '../common/namespace'; -import './stream_client_nodejs'; - -import '../common/livedata_connection'; +if (false) { + import "./stream_client_nodejs"; +} diff --git a/packages/ddp-client/server/stream_client_nodejs.js b/packages/ddp-client/server/stream_client_nodejs.js index 8bf1ba056c..7abae4d970 100644 --- a/packages/ddp-client/server/stream_client_nodejs.js +++ b/packages/ddp-client/server/stream_client_nodejs.js @@ -16,7 +16,7 @@ import StreamClientCommon from '../common/stream_client_common'; // We don't do any heartbeating. (The logic that did this in sockjs was removed, // because it used a built-in sockjs mechanism. We could do it with WebSocket // ping frames or with DDP-level messages.) -class ClientStream extends StreamClientCommon { +export default class ClientStream extends StreamClientCommon { constructor(endpoint, options) { super(); diff --git a/packages/ddp-client/test/stream_tests.js b/packages/ddp-client/test/stream_tests.js index 2d0e1c6af8..0a7f3b2bfd 100644 --- a/packages/ddp-client/test/stream_tests.js +++ b/packages/ddp-client/test/stream_tests.js @@ -1,6 +1,10 @@ import { LivedataTest } from '../common/namespace.js'; import { toSockjsUrl } from '../common/urlHelpers'; +import getClientStreamClass from '../common/getClientStreamClass'; + +const ClientStream = getClientStreamClass(); + Tinytest.add('stream - status', function(test) { // Very basic test. Just see that it runs and returns something. Not a // lot of coverage, but enough that it would have caught a recent bug. @@ -40,7 +44,7 @@ testAsyncMulti('stream - reconnect', [ testAsyncMulti('stream - basic disconnect', [ function(test, expect) { var history = []; - var stream = new LivedataTest.ClientStream('/'); + var stream = new ClientStream('/'); var onTestComplete = expect(function(unexpectedHistory) { stream.disconnect(); if (unexpectedHistory) { @@ -93,7 +97,7 @@ testAsyncMulti('stream - basic disconnect', [ testAsyncMulti('stream - disconnect remains offline', [ function(test, expect) { var history = []; - var stream = new LivedataTest.ClientStream('/'); + var stream = new ClientStream('/'); var onTestComplete = expect(function(unexpectedHistory) { stream.disconnect(); if (unexpectedHistory) {