Skip to content

Commit

Permalink
feat: make Mongoose arrays proxied plain arrays, remove instantiation…
Browse files Browse the repository at this point in the history
… of CoreMongooseArray

Re: #8884
Fix #7700
  • Loading branch information
vkarpov15 committed Jul 29, 2020
1 parent 96ed6c0 commit dfcc346
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 14 deletions.
2 changes: 1 addition & 1 deletion lib/types/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const _basePush = Array.prototype.push;
function MongooseArray(values, path, doc) {
// TODO: replace this with `new CoreMongooseArray().concat()` when we remove
// support for node 4.x and 5.x, see https://i.imgur.com/UAAHk4S.png
const arr = new CoreMongooseArray();
const arr = [];
arr[arrayAtomicsSymbol] = {};

if (Array.isArray(values)) {
Expand Down
30 changes: 18 additions & 12 deletions lib/types/arrayProxy.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use strict';

const CoreMongooseArray = require('./core_array');

module.exports = function arrayProxy(arr) {
const proxy = new Proxy(arr, {
get: function(target, prop) {
Expand All @@ -10,24 +12,17 @@ module.exports = function arrayProxy(arr) {
return arr;
}
if (prop === 'set') {
return function set(i, val, skipModified) {
if (skipModified) {
arr[i] = val;
return arr;
}
const value = arr._cast(val, i);
arr[i] = value;
arr._markModified(i);
return arr;
};
return set;
}
if (CoreMongooseArray.prototype.hasOwnProperty(prop)) {
return CoreMongooseArray.prototype[prop];
}

return target[prop];
},
set: function(target, prop, value) {
if (typeof prop === 'string' && /^\d+$/.test(prop)) {
// console.log('Set', prop, value, new Error().stack);
target.set(prop, value);
set(prop, value);
} else {
target[prop] = value;
}
Expand All @@ -36,5 +31,16 @@ module.exports = function arrayProxy(arr) {
}
});

function set(i, val, skipModified) {
if (skipModified) {
arr[i] = val;
return arr;
}
const value = CoreMongooseArray.prototype._cast.call(arr, val, i);
arr[i] = value;
CoreMongooseArray.prototype._markModified.call(arr, i);
return arr;
}

return proxy;
};
5 changes: 4 additions & 1 deletion lib/types/core_array.js
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,10 @@ class CoreMongooseArray extends Array {

pull() {
const values = [].map.call(arguments, this._cast, this);
const cur = this[arrayParentSymbol].get(this[arrayPathSymbol]);
let cur = this[arrayParentSymbol].get(this[arrayPathSymbol]);
if (cur.isMongooseArrayProxy) {
cur = cur.__array;
}
let i = cur.length;
let mem;

Expand Down
1 change: 1 addition & 0 deletions test/types.array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ describe('types array', function() {
const doc = new Test({ arr: ['test'] });

assert.deepEqual(doc.arr, new MongooseArray(['test']));
assert.deepEqual(doc.arr, ['test']);

done();
});
Expand Down

0 comments on commit dfcc346

Please sign in to comment.