diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 321a5cba..1ab5a8da 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ on: [push, pull_request] jobs: test: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: matrix: meteor: [1.12.2, 2.8.1, 2.12, 2.15] @@ -19,14 +19,14 @@ jobs: redis-version: ${{ matrix.redis-version }} - name: Setup Meteor - uses: meteorengineer/setup-meteor@v1 + uses: meteorengineer/setup-meteor@v2 with: meteor-release: ${{ matrix.meteor }} - name: Setup tests run: | meteor create --release ${{ matrix.meteor }} --bare test cd test - meteor npm i --save puppeteer@1.18.1 simpl-schema@1.13.1 chai + meteor npm i --save puppeteer@1.18.1 simpl-schema@1.13.1 chai@4 - name: Test working-directory: ./test run: METEOR_PACKAGE_DIRS="../" TEST_BROWSER_DRIVER=puppeteer meteor test-packages --raw-logs --once --driver-package meteortesting:mocha ../ diff --git a/.gitignore b/.gitignore index 04913f99..3668c4f1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ npm-debug.log .idea/ test/ +node_modules/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d5584094..4f320225 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,8 @@ First, thank you for considering contributing to redis-oplog! It's people like you that make the open source community such a great community! 😊 -We welcome any type of contribution, not only code. You can help with +We welcome any type of contribution, not only code. You can help with + - **QA**: file bug reports, the more details you can give the better (e.g. screenshots with the console open) - **Marketing**: writing blog posts, howto's, printing stickers, ... - **Community**: presenting the project at meetups, organizing a dedicated meetup for the local community, ... @@ -13,7 +14,7 @@ We welcome any type of contribution, not only code. You can help with ## Your First Contribution -Working on your first Pull Request? You can learn how from this *free* series, [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github). +Working on your first Pull Request? You can learn how from this _free_ series, [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github). ## Submitting code @@ -26,14 +27,16 @@ It is also always helpful to have some context for your pull request. What was t ## Running Tests -### Setup +### Setup + ``` meteor create --release 1.12.2 --bare test cd test -meteor npm i --save puppeteer@1.18.1 simpl-schema chai +meteor npm i --save puppeteer@1.18.1 simpl-schema chai@4 ``` ### Start Tests + ``` METEOR_PACKAGE_DIRS="../" TEST_BROWSER_DRIVER=puppeteer meteor test-packages --raw-logs --once --driver-package meteortesting:mocha ../ ``` @@ -55,14 +58,12 @@ You can also reach us at hello@redis-oplog.opencollective.com. Thank you to all the people who have already contributed to redis-oplog! - ### Backers Thank you to all our backers! [[Become a backer](https://opencollective.com/redis-oplog#backer)] - ### Sponsors Thank you to all our sponsors! (please ask your company to also support this open source project by [becoming a sponsor](https://opencollective.com/redis-oplog#sponsor)) diff --git a/lib/cache/ObservableCollection.js b/lib/cache/ObservableCollection.js index 127171df..5545b282 100644 --- a/lib/cache/ObservableCollection.js +++ b/lib/cache/ObservableCollection.js @@ -196,11 +196,12 @@ export default class ObservableCollection { * @param safe {Boolean} If this is set to true, it assumes that the object is cleaned */ add(doc, safe = false) { - doc = EJSON.clone(doc); - if (!safe) { if (this.fieldsArray) { + // projection function clones the document already. doc = this.projectFieldsOnDoc(doc); + } else { + doc = EJSON.clone(doc); } } diff --git a/lib/mongo/ObserveMultiplex.js b/lib/mongo/ObserveMultiplex.js index 53e0c103..3a80c64c 100644 --- a/lib/mongo/ObserveMultiplex.js +++ b/lib/mongo/ObserveMultiplex.js @@ -41,6 +41,15 @@ export function ObserveMultiplexer(options) { }); } +function strictFreeze(obj) { + return new Proxy(obj, { + set() { + throw new Error('Cannot mutate a frozen object'); + } + }); +} +const freezeObject = Meteor.isProduction ? Object.freeze : strictFreeze + Object.assign(ObserveMultiplexer.prototype, { addHandleAndSendInitialAdds: function(handle) { var self = this; @@ -213,16 +222,17 @@ Object.assign(ObserveMultiplexer.prototype, { // can continue until these are done. (But we do have to be careful to not // use a handle that got removed, because removeHandle does not use the // queue; thus, we iterate over an array of keys that we control.) + const safeArgs = freezeObject(args); + Object.keys(self._handles).forEach(function(handleId) { var handle = self._handles && self._handles[handleId]; if (!handle) return; var callback = handle['_' + callbackName]; - // clone arguments so that callbacks can mutate their arguments // We silence out removed exceptions if (callback === 'removed') { try { - callback.apply(null, EJSON.clone(args)); + callback.apply(null, safeArgs); } catch (e) { // Supressing `removed non-existent exceptions` if (!isRemovedNonExistent(e)) { @@ -230,7 +240,7 @@ Object.assign(ObserveMultiplexer.prototype, { } } } else { - callback && callback.apply(null, EJSON.clone(args)); + callback && callback.apply(null, safeArgs); } }); }); @@ -250,8 +260,7 @@ Object.assign(ObserveMultiplexer.prototype, { self._cache.docs.forEach(function(doc, id) { if (!_.has(self._handles, handle._id)) throw Error('handle got removed before sending initial adds!'); - var fields = EJSON.clone(doc); - delete fields._id; + const { _id, ...fields } = doc if (self._ordered) add(id, fields, null); // we're going in order, so add at end else add(id, fields); diff --git a/package.js b/package.js index 48bebfa5..a5ac9cc0 100644 --- a/package.js +++ b/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'cultofcoders:redis-oplog', - version: '2.2.2', + version: '2.3.0', // Brief, one-line summary of the package. summary: "Replacement for Meteor's MongoDB oplog implementation", // URL to the Git repository containing the source code for this package. @@ -17,7 +17,7 @@ Npm.depends({ }); Package.onUse(function(api) { - api.versionsFrom(['1.12.2', '2.8.1', '2.13', '2.15']); + api.versionsFrom(['1.12.2', '2.8.1', '2.13', '2.15', '2.16']); api.use([ 'underscore', 'ecmascript',