diff --git a/packages/observe-sequence/observe_sequence.js b/packages/observe-sequence/observe_sequence.js index 54fbfed19..eccbbc476 100644 --- a/packages/observe-sequence/observe_sequence.js +++ b/packages/observe-sequence/observe_sequence.js @@ -1,3 +1,17 @@ +const isObject = function (value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); +} +const has = function (obj, key) { + var keyParts = key.split('.'); + + return !!obj && ( + keyParts.length > 1 + ? has(obj[key.split('.')[0]], keyParts.slice(1).join('.')) + : hasOwnProperty.call(obj, key) + ); +}; + const warn = function () { if (ObserveSequence._suppressWarnings) { ObserveSequence._suppressWarnings--; @@ -15,7 +29,7 @@ const warn = function () { // subclassed arrays: instanceof Array === true, _.isArray(arr) === false // see specific tests function isArray(arr) { - return arr instanceof Array || _.isArray(arr); + return arr instanceof Array || Array.isArray(arr); } const idStringify = MongoID.idStringify; @@ -94,7 +108,7 @@ ObserveSequence = { if (activeObserveHandle) { // If we were previously observing a cursor, replace lastSeqArray with // more up-to-date information. Then stop the old observe. - lastSeqArray = _.map(lastSeq.fetch(), function (doc) { + lastSeqArray = lastSeq.fetch().map(function (doc) { return {_id: doc._id, item: doc}; }); activeObserveHandle.stop(); @@ -204,9 +218,13 @@ const badSequenceError = function (sequence) { sequenceGotValue(sequence)); }; +const isFunction = (func) => { + return typeof func === "function"; +} + const isStoreCursor = function (cursor) { - return cursor && _.isObject(cursor) && - _.isFunction(cursor.observe) && _.isFunction(cursor.fetch); + return cursor && isObject(cursor) && + isFunction(cursor.observe) && isFunction(cursor.fetch); }; // Calculates the differences between `lastSeqArray` and @@ -221,11 +239,11 @@ const diffArray = function (lastSeqArray, seqArray, callbacks) { var posCur = {}; var lengthCur = lastSeqArray.length; - _.each(seqArray, function (doc, i) { + seqArray.forEach(function (doc, i) { newIdObjects.push({_id: doc._id}); posNew[idStringify(doc._id)] = i; }); - _.each(lastSeqArray, function (doc, i) { + lastSeqArray.forEach(function (doc, i) { oldIdObjects.push({_id: doc._id}); posOld[idStringify(doc._id)] = i; posCur[idStringify(doc._id)] = i; @@ -242,7 +260,7 @@ const diffArray = function (lastSeqArray, seqArray, callbacks) { if (before) { // If not adding at the end, we need to update indexes. // XXX this can still be improved greatly! - _.each(posCur, function (pos, id) { + Object.entries(posCur).forEach(function ([id, pos]) { if (pos >= position) posCur[id]++; }); @@ -285,7 +303,7 @@ const diffArray = function (lastSeqArray, seqArray, callbacks) { // 2. The element is moved back. Then the positions in between *and* the // element that is currently standing on the moved element's future // position are moved forward. - _.each(posCur, function (elCurPosition, id) { + Object.entries(posCur).forEach(function ([id, elCurPosition]) { if (oldPosition < elCurPosition && elCurPosition < newPosition) posCur[id]--; else if (newPosition <= elCurPosition && elCurPosition < oldPosition) @@ -305,7 +323,7 @@ const diffArray = function (lastSeqArray, seqArray, callbacks) { removed: function (id) { var prevPosition = posCur[idStringify(id)]; - _.each(posCur, function (pos, id) { + Object.entries(posCur).forEach(function ([id, pos]) { if (pos >= prevPosition) posCur[id]--; }); @@ -319,10 +337,12 @@ const diffArray = function (lastSeqArray, seqArray, callbacks) { prevPosition); } }); + + Object.entries(posNew).forEach(function ([idString, pos]) { - _.each(posNew, function (pos, idString) { var id = idParse(idString); - if (_.has(posOld, idString)) { + + if (has(posOld, idString)) { // specifically for primitive types, compare equality before // firing the 'changedAt' callback. otherwise, always fire it // because doing a deep EJSON comparison is not guaranteed to @@ -345,7 +365,7 @@ seqChangedToEmpty = function (lastSeqArray, callbacks) { seqChangedToArray = function (lastSeqArray, array, callbacks) { var idsUsed = {}; - var seqArray = _.map(array, function (item, index) { + var seqArray = array.map(function (item, index) { var id; if (typeof item === 'string') { // ensure not empty, since other layers (eg DomRange) assume this as well diff --git a/packages/observe-sequence/observe_sequence_tests.js b/packages/observe-sequence/observe_sequence_tests.js index 55ab55e8b..bfb9af090 100644 --- a/packages/observe-sequence/observe_sequence_tests.js +++ b/packages/observe-sequence/observe_sequence_tests.js @@ -20,11 +20,11 @@ runOneObserveSequenceTestCase = function (test, sequenceFunc, var firedCallbacks = []; var handle = ObserveSequence.observe(sequenceFunc, { - addedAt: function () { - firedCallbacks.push({addedAt: _.toArray(arguments)}); + addedAt: function (...args) { + firedCallbacks.push({addedAt: args}); }, - changedAt: function () { - var obj = {changedAt: _.toArray(arguments)}; + changedAt: function (...args) { + var obj = {changedAt: args}; // Browsers are inconsistent about the order in which 'changedAt' // callbacks fire. To ensure consistent behavior of these tests, @@ -45,11 +45,11 @@ runOneObserveSequenceTestCase = function (test, sequenceFunc, firedCallbacks.splice(i, 0, obj); }, - removedAt: function () { - firedCallbacks.push({removedAt: _.toArray(arguments)}); + removedAt: function (...args) { + firedCallbacks.push({removedAt: args}); }, - movedTo: function () { - firedCallbacks.push({movedTo: _.toArray(arguments)}); + movedTo: function (...args) { + firedCallbacks.push({movedTo: args}); } }); @@ -69,11 +69,11 @@ runOneObserveSequenceTestCase = function (test, sequenceFunc, var commonLength = Math.min(firedCallbacks.length, expectedCallbacks.length); for (var i = 0; i < commonLength; i++) { var callback = expectedCallbacks[i]; - if (_.keys(callback).length !== 1) + if (Object.keys(callback).length !== 1) throw new Error("Callbacks should be objects with one key, eg `addedAt`"); - var callbackName = _.keys(callback)[0]; - var args = _.values(callback)[0]; - _.each(args, function (arg, argIndex) { + var callbackName = Object.keys(callback)[0]; + var args = Object.values(callback)[0]; + args.forEach(function (arg, argIndex) { if (arg && typeof arg === 'object' && 'NOT' in arg && firedCallbacks[i][callbackName]) { @@ -544,7 +544,7 @@ Tinytest.add('observe-sequence - cursor to other cursor', function (test) { Tinytest.add('observe-sequence - cursor to other cursor with transform', function (test) { var dep = new Tracker.Dependency; var transform = function(doc) { - return _.extend({idCopy: doc._id}, doc); + return Object.assign({idCopy: doc._id}, doc); }; var coll = new Mongo.Collection(null, {transform: transform}); @@ -678,7 +678,7 @@ Tinytest.add('observe-sequence - vm generated number arrays', function (test) { }); Tinytest.add('observe-sequence - number arrays, _id:0 correctly handled, no duplicate ids warning #4049', function (test) { - var seq = _.map(_.range(3), function (i) { return { _id: i}; }); + var seq = [...Array(3).keys()].map(function (i) { return { _id: i}; }); var dep = new Tracker.Dependency; runOneObserveSequenceTestCase(test, function () { @@ -689,7 +689,7 @@ Tinytest.add('observe-sequence - number arrays, _id:0 correctly handled, no dupl // _id. An expression like `(item && item._id) || index` would incorrectly // return '2' for the last item because the _id is falsy (although it is not // undefined, but 0!). - seq = _.map([1, 2, 0], function (i) { return { _id: i}; }); + seq = [1, 2, 0].map(function (i) { return { _id: i}; }); dep.changed(); }, [ {addedAt: [0, {_id: 0}, 0, null]}, diff --git a/packages/observe-sequence/package.js b/packages/observe-sequence/package.js index dd11afa63..f39579115 100644 --- a/packages/observe-sequence/package.js +++ b/packages/observe-sequence/package.js @@ -7,7 +7,6 @@ Package.onUse(function (api) { api.use('tracker@1.2.0'); api.use('mongo-id@1.0.8'); // for idStringify api.use('diff-sequence@1.1.1'); - api.use('underscore@1.0.10'); api.use('random@1.2.0'); api.export('ObserveSequence'); api.addFiles(['observe_sequence.js']); @@ -17,7 +16,6 @@ Package.onTest(function (api) { api.use([ 'tinytest', 'observe-sequence', - 'underscore', 'ejson', 'tracker', 'mongo'