Merge pull request #12259 from harryadel/underscore/ddp-server

[ddp-server] Remove underscore
This commit is contained in:
Denilson
2024-10-01 13:07:58 -04:00
committed by GitHub
6 changed files with 88 additions and 95 deletions

View File

@@ -16,11 +16,11 @@ DDPServer._Crossbar = function (options) {
self.factName = options.factName || null;
};
_.extend(DDPServer._Crossbar.prototype, {
Object.assign(DDPServer._Crossbar.prototype, {
// msg is a trigger or a notification
_collectionForMessage: function (msg) {
var self = this;
if (! _.has(msg, 'collection')) {
if (!('collection' in msg)) {
return '';
} else if (typeof(msg.collection) === 'string') {
if (msg.collection === '')
@@ -47,7 +47,7 @@ _.extend(DDPServer._Crossbar.prototype, {
var collection = self._collectionForMessage(trigger);
var record = {trigger: EJSON.clone(trigger), callback: callback};
if (! _.has(self.listenersByCollection, collection)) {
if (! (collection in self.listenersByCollection)) {
self.listenersByCollection[collection] = {};
self.listenersByCollectionCount[collection] = 0;
}
@@ -88,13 +88,13 @@ _.extend(DDPServer._Crossbar.prototype, {
var collection = self._collectionForMessage(notification);
if (! _.has(self.listenersByCollection, collection)) {
if (!(collection in self.listenersByCollection)) {
return;
}
var listenersForCollection = self.listenersByCollection[collection];
var callbackIds = [];
_.each(listenersForCollection, function (l, id) {
Object.entries(listenersForCollection).forEach(function ([id, l]) {
if (self._matches(notification, l.trigger)) {
callbackIds.push(id);
}
@@ -110,7 +110,7 @@ _.extend(DDPServer._Crossbar.prototype, {
// first gets reduced down to the empty object (and then never gets
// increased again).
for (const id of callbackIds) {
if (_.has(listenersForCollection, id)) {
if (id in listenersForCollection) {
await listenersForCollection[id].callback(notification);
}
}
@@ -150,10 +150,9 @@ _.extend(DDPServer._Crossbar.prototype, {
return false;
}
return _.all(trigger, function (triggerValue, key) {
return !_.has(notification, key) ||
EJSON.equals(triggerValue, notification[key]);
});
return Object.keys(trigger).every(function (key) {
return !(key in notification) || EJSON.equals(trigger[key], notification[key]);
});
}
});
@@ -164,4 +163,4 @@ _.extend(DDPServer._Crossbar.prototype, {
// message from being sent).
DDPServer._InvalidationCrossbar = new DDPServer._Crossbar({
factName: "invalidation-crossbar-listeners"
});
});

View File

@@ -1,5 +1,10 @@
import isEmpty from 'lodash.isempty';
import isString from 'lodash.isstring';
import isObject from 'lodash.isobject';
DDPServer = {};
// Publication strategies define how we handle data from published cursors at the collection level
// This allows someone to:
// - Choose a trade-off between client-server bandwidth and server memory usage
@@ -89,7 +94,7 @@ DDPServer._getCurrentFence = function () {
return currentInvocation ? currentInvocation.fence : undefined;
};
_.extend(SessionDocumentView.prototype, {
Object.assign(SessionDocumentView.prototype, {
getFields: function () {
var self = this;
@@ -197,7 +202,7 @@ Object.assign(SessionCollectionView.prototype, {
diff: function (previous) {
var self = this;
DiffSequence.diffMaps(previous.documents, self.documents, {
both: _.bind(self.diffDocument, self),
both: self.diffDocument.bind(self),
rightOnly: function (id, nowDV) {
self.callbacks.added(self.collectionName, id, nowDV.getFields());
@@ -243,7 +248,7 @@ Object.assign(SessionCollectionView.prototype, {
}
docView.existsIn.add(subscriptionHandle);
var changeCollector = {};
_.each(fields, function (value, key) {
Object.entries(fields).forEach(function ([key, value]) {
docView.changeField(
subscriptionHandle, key, value, changeCollector, true);
});
@@ -259,7 +264,7 @@ Object.assign(SessionCollectionView.prototype, {
var docView = self.documents.get(id);
if (!docView)
throw new Error("Could not find element with id " + id + " to change");
_.each(changed, function (value, key) {
Object.entries(changed).forEach(function ([key, value]) {
if (value === undefined)
docView.clearField(subscriptionHandle, key, changedResult);
else
@@ -401,7 +406,7 @@ Object.assign(Session.prototype, {
if (self._isSending) {
self.send({msg: "ready", subs: subscriptionIds});
} else {
_.each(subscriptionIds, function (subscriptionId) {
subscriptionIds.forEach(function (subscriptionId) {
self._pendingReady.push(subscriptionId);
});
}
@@ -419,7 +424,7 @@ Object.assign(Session.prototype, {
},
sendChanged(collectionName, id, fields) {
if (_.isEmpty(fields))
if (isEmpty(fields))
return;
if (this._canSend(collectionName)) {
@@ -441,9 +446,9 @@ Object.assign(Session.prototype, {
getSendCallbacks: function () {
var self = this;
return {
added: _.bind(self.sendAdded, self),
changed: _.bind(self.sendChanged, self),
removed: _.bind(self.sendRemoved, self)
added: self.sendAdded.bind(self),
changed: self.sendChanged.bind(self),
removed: self.sendRemoved.bind(self)
};
},
@@ -493,8 +498,8 @@ Object.assign(Session.prototype, {
// Make a shallow copy of the set of universal handlers and start them. If
// additional universal publishers start while we're running them (due to
// yielding), they will run separately as part of Server.publish.
var handlers = _.clone(self.server.universal_publish_handlers);
_.each(handlers, function (handler) {
var handlers = [...self.server.universal_publish_handlers];
handlers.forEach(function (handler) {
self._startSubscription(handler);
});
},
@@ -536,7 +541,7 @@ Object.assign(Session.prototype, {
// Defer calling the close callbacks, so that the caller closing
// the session isn't waiting for all the callbacks to complete.
_.each(self._closeCallbacks, function (callback) {
self._closeCallbacks.forEach(function (callback) {
callback();
});
});
@@ -639,7 +644,7 @@ Object.assign(Session.prototype, {
return true;
});
if (_.has(self.protocol_handlers, msg.msg)) {
if (msg.msg in self.protocol_handlers) {
const result = self.protocol_handlers[msg.msg].call(
self,
msg,
@@ -674,7 +679,7 @@ Object.assign(Session.prototype, {
// reject malformed messages
if (typeof (msg.id) !== "string" ||
typeof (msg.name) !== "string" ||
(('params' in msg) && !(msg.params instanceof Array))) {
('params' in msg && !(msg.params instanceof Array))) {
self.sendError("Malformed subscription", msg);
return;
}
@@ -743,7 +748,7 @@ Object.assign(Session.prototype, {
// for forwards compatibility.
if (typeof (msg.id) !== "string" ||
typeof (msg.method) !== "string" ||
(('params' in msg) && !(msg.params instanceof Array)) ||
('params' in msg && !(msg.params instanceof Array)) ||
(('randomSeed' in msg) && (typeof msg.randomSeed !== "string"))) {
self.sendError("Malformed method invocation", msg);
return;
@@ -814,34 +819,16 @@ Object.assign(Session.prototype, {
}
}
const getCurrentMethodInvocationResult = () =>
DDP._CurrentMethodInvocation.withValue(
resolve(DDPServer._CurrentWriteFence.withValue(
fence,
() => DDP._CurrentMethodInvocation.withValue(
invocation,
() =>
maybeAuditArgumentChecks(
handler,
invocation,
msg.params,
"call to '" + msg.method + "'"
),
{
name: 'getCurrentMethodInvocationResult',
keyName: 'getCurrentMethodInvocationResult',
}
);
resolve(
DDPServer._CurrentWriteFence.withValue(
fence,
getCurrentMethodInvocationResult,
{
name: 'DDPServer._CurrentWriteFence',
keyName: '_CurrentWriteFence',
}
() => maybeAuditArgumentChecks(
handler, invocation, msg.params,
"call to '" + msg.method + "'"
)
)
);
));
});
async function finish() {
@@ -961,7 +948,7 @@ Object.assign(Session.prototype, {
Meteor._noYieldsAllowed(function () {
self._isSending = true;
self._diffCollectionViews(beforeCVs);
if (!_.isEmpty(self._pendingReady)) {
if (!isEmpty(self._pendingReady)) {
self.sendReady(self._pendingReady);
self._pendingReady = [];
}
@@ -1050,7 +1037,7 @@ Object.assign(Session.prototype, {
return self.socket.remoteAddress;
var forwardedFor = self.socket.headers["x-forwarded-for"];
if (! _.isString(forwardedFor))
if (!isString(forwardedFor))
return null;
forwardedFor = forwardedFor.trim().split(/\s*,\s*/);
@@ -1244,9 +1231,9 @@ Object.assign(Subscription.prototype, {
// _publishCursor only returns after the initial added callbacks have run.
// mark subscription as ready.
self.ready();
} else if (_.isArray(res)) {
} else if (Array.isArray(res)) {
// Check all the elements are cursors
if (! _.all(res, isCursor)) {
if (! res.every(isCursor)) {
self.error(new Error("Publish function returned an array of non-Cursors"));
return;
}
@@ -1257,7 +1244,7 @@ Object.assign(Subscription.prototype, {
for (var i = 0; i < res.length; ++i) {
var collectionName = res[i]._getCollectionName();
if (_.has(collectionNames, collectionName)) {
if (collectionNames[collectionName]) {
self.error(new Error(
"Publish function returned multiple cursors for collection " +
collectionName));
@@ -1302,7 +1289,7 @@ Object.assign(Subscription.prototype, {
// Tell listeners, so they can clean up
var callbacks = self._stopCallbacks;
self._stopCallbacks = [];
_.each(callbacks, function (callback) {
callbacks.forEach(function (callback) {
callback();
});
},
@@ -1589,33 +1576,33 @@ Object.assign(Server.prototype, {
},
/**
* @summary Set publication strategy for the given collection. Publications strategies are available from `DDPServer.publicationStrategies`. You call this method from `Meteor.server`, like `Meteor.server.setPublicationStrategy()`
* @summary Set publication strategy for the given publication. Publications strategies are available from `DDPServer.publicationStrategies`. You call this method from `Meteor.server`, like `Meteor.server.setPublicationStrategy()`
* @locus Server
* @alias setPublicationStrategy
* @param collectionName {String}
* @param publicationName {String}
* @param strategy {{useCollectionView: boolean, doAccountingForCollection: boolean}}
* @memberOf Meteor.server
* @importFromPackage meteor
*/
setPublicationStrategy(collectionName, strategy) {
setPublicationStrategy(publicationName, strategy) {
if (!Object.values(publicationStrategies).includes(strategy)) {
throw new Error(`Invalid merge strategy: ${strategy}
for collection ${collectionName}`);
for collection ${publicationName}`);
}
this._publicationStrategies[collectionName] = strategy;
this._publicationStrategies[publicationName] = strategy;
},
/**
* @summary Gets the publication strategy for the requested collection. You call this method from `Meteor.server`, like `Meteor.server.getPublicationStrategy()`
* @summary Gets the publication strategy for the requested publication. You call this method from `Meteor.server`, like `Meteor.server.getPublicationStrategy()`
* @locus Server
* @alias getPublicationStrategy
* @param collectionName {String}
* @param publicationName {String}
* @memberOf Meteor.server
* @importFromPackage meteor
* @return {{useCollectionView: boolean, doAccountingForCollection: boolean}}
*/
getPublicationStrategy(collectionName) {
return this._publicationStrategies[collectionName]
getPublicationStrategy(publicationName) {
return this._publicationStrategies[publicationName]
|| this.options.defaultPublicationStrategy;
},
@@ -1637,9 +1624,9 @@ Object.assign(Server.prototype, {
// The connect message must specify a version and an array of supported
// versions, and it must claim to support what it is proposing.
if (!(typeof (msg.version) === 'string' &&
_.isArray(msg.support) &&
_.all(msg.support, _.isString) &&
_.contains(msg.support, msg.version))) {
Array.isArray(msg.support) &&
msg.support.every(isString) &&
msg.support.includes(msg.version))) {
socket.send(DDPCommon.stringifyDDP({msg: 'failed',
version: DDPCommon.SUPPORTED_DDP_VERSIONS[0]}));
socket.close();
@@ -1704,7 +1691,7 @@ Object.assign(Server.prototype, {
publish: function (name, handler, options) {
var self = this;
if (! _.isObject(name)) {
if (!isObject(name)) {
options = options || {};
if (name && name in self.publish_handlers) {
@@ -1752,7 +1739,7 @@ Object.assign(Server.prototype, {
}
}
else{
_.each(name, function(value, key) {
Object.entries(name).forEach(function([key, value]) {
self.publish(key, value, {});
});
}
@@ -1783,7 +1770,7 @@ Object.assign(Server.prototype, {
*/
methods: function (methods) {
var self = this;
_.each(methods, function (func, name) {
Object.entries(methods).forEach(function ([name, func]) {
if (typeof func !== 'function')
throw new Error("Method '" + name + "' must be a function");
if (self.method_handlers[name])
@@ -1923,8 +1910,8 @@ Object.assign(Server.prototype, {
var calculateVersion = function (clientSupportedVersions,
serverSupportedVersions) {
var correctVersion = _.find(clientSupportedVersions, function (version) {
return _.contains(serverSupportedVersions, version);
var correctVersion = clientSupportedVersions.find(function (version) {
return serverSupportedVersions.includes(version);
});
if (!correctVersion) {
correctVersion = serverSupportedVersions[0];
@@ -1964,8 +1951,7 @@ var wrapInternalException = function (exception, context) {
// Did the error contain more details that could have been useful if caught in
// server code (or if thrown from non-client-originated code), but also
// provided a "sanitized" version with more context than 500 Internal server
// error? Use that.
// provided a "sanitized" version with more context than 500 Internal server error? Use that.
if (exception.sanitizedError) {
if (exception.sanitizedError.isClientSafe)
return exception.sanitizedError;
@@ -1986,4 +1972,4 @@ var maybeAuditArgumentChecks = function (f, context, args, description) {
f, context, args, description);
}
return f.apply(context, args);
};
};

View File

@@ -7,6 +7,10 @@ Package.describe({
Npm.depends({
"permessage-deflate": "0.1.7",
sockjs: "0.3.24",
"lodash.once": "4.1.1",
"lodash.isempty": "4.4.0",
"lodash.isstring": "4.0.1",
"lodash.isobject": "3.0.2"
});
Package.onUse(function (api) {
@@ -15,7 +19,6 @@ Package.onUse(function (api) {
"check",
"random",
"ejson",
"underscore",
"retry",
"mongo-id",
"diff-sequence",
@@ -62,7 +65,6 @@ Package.onTest(function (api) {
api.use("mongo", ["client", "server"]);
api.use("test-helpers", ["client", "server"]);
api.use([
"underscore",
"tinytest",
"random",
"tracker",

View File

@@ -11,7 +11,7 @@ Meteor.refresh = async function (notification) {
// Proxy the public methods of Meteor.server so they can
// be called directly on Meteor.
_.each(
[
'publish',
'isAsyncCall',
@@ -22,8 +22,8 @@ _.each(
'applyAsync',
'onConnection',
'onMessage',
],
].forEach(
function(name) {
Meteor[name] = _.bind(Meteor.server[name], Meteor.server);
Meteor[name] = Meteor.server[name].bind(Meteor.server);
}
);

View File

@@ -1,3 +1,5 @@
import isEmpty from 'lodash.isempty';
var newView = function(test) {
var results = [];
var view = new DDPServer._SessionCollectionView('test', {
@@ -5,7 +7,7 @@ var newView = function(test) {
results.push({fun: 'added', id: id, fields: fields});
},
changed: function (collection, id, changed) {
if (_.isEmpty(changed))
if (isEmpty(changed))
return;
results.push({fun: 'changed', id: id, changed: changed});
},
@@ -17,8 +19,8 @@ var newView = function(test) {
view: view,
results: results
};
_.each(["added", "changed", "removed"], function (it) {
v[it] = _.bind(view[it], view);
["added", "changed", "removed"].forEach(function (it) {
v[it] = view[it].bind(view);
});
v.expectResult = function (result) {
test.equal(results.shift(), result);
@@ -182,7 +184,7 @@ Tinytest.add('livedata - sessionview - change to canonical value produces no cha
v.added("B", "A1", {foo: "baz"});
var canon = "bar";
var maybeResults = v.drain();
if (!_.isEmpty(maybeResults)) {
if (!isEmpty(maybeResults)) {
// if something happened, it was a change message to baz.
// if nothing did, canon is still bar.
test.length(maybeResults, 1);
@@ -390,4 +392,4 @@ Tinytest.add('livedata - sessionview - clear undefined value', function (test) {
v.changed("A", "A1", {field: undefined});
v.expectNoResult();
});
});

View File

@@ -1,3 +1,5 @@
import once from 'lodash.once';
// By default, we use the permessage-deflate extension with default
// configuration. If $SERVER_WEBSOCKET_COMPRESSION is set, then it must be valid
// JSON. If it represents a falsey value, then we do not use permessage-deflate
@@ -9,7 +11,7 @@
// crash the tool during isopacket load if your JSON doesn't parse. This is only
// a problem because the tool has to load the DDP server code just in order to
// be a DDP client; see https://github.com/meteor/meteor/issues/3452 .)
var websocketExtensions = _.once(function () {
var websocketExtensions = once(function () {
var extensions = [];
var websocketCompressionConfig = process.env.SERVER_WEBSOCKET_COMPRESSION
@@ -116,7 +118,9 @@ StreamServer = function () {
socket.write(data);
};
socket.on('close', function () {
self.open_sockets = _.without(self.open_sockets, socket);
self.open_sockets = self.open_sockets.filter(function(value) {
return value !== socket;
});
});
self.open_sockets.push(socket);
@@ -128,7 +132,7 @@ StreamServer = function () {
// call all our callbacks when we get a new socket. they will do the
// work of setting up handlers and such for specific messages.
_.each(self.registration_callbacks, function (callback) {
self.registration_callbacks.forEach(function (callback) {
callback(socket);
});
});
@@ -141,7 +145,7 @@ Object.assign(StreamServer.prototype, {
register: function (callback) {
var self = this;
self.registration_callbacks.push(callback);
_.each(self.all_sockets(), function (socket) {
self.all_sockets().forEach(function (socket) {
callback(socket);
});
},
@@ -149,7 +153,7 @@ Object.assign(StreamServer.prototype, {
// get a list of all sockets
all_sockets: function () {
var self = this;
return _.values(self.open_sockets);
return Object.values(self.open_sockets);
},
// Redirect /websocket to /sockjs/websocket in order to not expose
@@ -183,11 +187,11 @@ Object.assign(StreamServer.prototype, {
parsedUrl.pathname = self.prefix + '/websocket';
request.url = url.format(parsedUrl);
}
_.each(oldHttpServerListeners, function(oldListener) {
oldHttpServerListeners.forEach(function(oldListener) {
oldListener.apply(httpServer, args);
});
};
httpServer.addListener(event, newListener);
});
}
});
});