From d2fb9916818a6b81249b4f9006383188fe10b49f Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Wed, 12 May 2021 00:19:16 -0400 Subject: [PATCH 01/16] Add .meteorignore to prevent publishing node_modules --- packages/react-meteor-data/.meteorignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 packages/react-meteor-data/.meteorignore diff --git a/packages/react-meteor-data/.meteorignore b/packages/react-meteor-data/.meteorignore new file mode 100644 index 00000000..fc195154 --- /dev/null +++ b/packages/react-meteor-data/.meteorignore @@ -0,0 +1,3 @@ +node_modules +package.json +package-lock-json From 335960d06fbbc8eb10949f560445d06df6d593d2 Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Wed, 12 May 2021 00:21:20 -0400 Subject: [PATCH 02/16] Add .gitignore to avoid comitting node_modules --- packages/react-mongo/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/react-mongo/.gitignore diff --git a/packages/react-mongo/.gitignore b/packages/react-mongo/.gitignore new file mode 100644 index 00000000..b512c09d --- /dev/null +++ b/packages/react-mongo/.gitignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file From 9018cac3eb3c815045a33ccaba25a290e40c3ad7 Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Wed, 12 May 2021 00:21:47 -0400 Subject: [PATCH 03/16] Make it clearer that all the package.json files are for dev purposes only --- packages/react-meteor-data/package-lock.json | 625 +++---------------- packages/react-meteor-data/package.json | 2 +- 2 files changed, 87 insertions(+), 540 deletions(-) diff --git a/packages/react-meteor-data/package-lock.json b/packages/react-meteor-data/package-lock.json index 8b543f4c..c4fe85cf 100644 --- a/packages/react-meteor-data/package-lock.json +++ b/packages/react-meteor-data/package-lock.json @@ -1,524 +1,13 @@ { "name": "react-meteor-data", - "lockfileVersion": 2, "requires": true, - "packages": { - "": { - "dependencies": { - "@testing-library/react": "^10.4.9", - "@types/meteor": "^1.4.70", - "@types/react": "^16.14.6", - "fast-deep-equal": "^3.1.3", - "react": "16.14.0", - "react-dom": "16.14.0", - "react-test-renderer": "16.14.0" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", - "dependencies": { - "@babel/highlight": "^7.12.13" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" - }, - "node_modules/@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.14.0", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.0.tgz", - "integrity": "sha512-0R0HTZWHLk6G8jIk0FtoX+AatCtKnswS98VhXwGImFc759PJRp4Tru0PQYZofyijTFUr+gT8Mu7sgXVJLQ0ceg==", - "dependencies": { - "core-js-pure": "^3.0.0", - "regenerator-runtime": "^0.13.4" - } - }, - "node_modules/@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": ">= 10.14.2" - } - }, - "node_modules/@testing-library/dom": { - "version": "7.31.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.0.tgz", - "integrity": "sha512-0X7ACg4YvTRDFMIuTOEj6B4NpN7i3F/4j5igOcTI5NC5J+N4TribNdErCHOZF1LBWhhcyfwxelVwvoYNMUXTOA==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^4.2.2", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.4", - "lz-string": "^1.4.4", - "pretty-format": "^26.6.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@testing-library/react": { - "version": "10.4.9", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-10.4.9.tgz", - "integrity": "sha512-pHZKkqUy0tmiD81afs8xfiuseXfU/N7rAX3iKjeZYje86t9VaB0LrxYVa+OOsvkrveX5jCK3IjajVn2MbePvqA==", - "dependencies": { - "@babel/runtime": "^7.10.3", - "@testing-library/dom": "^7.22.3" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@types/aria-query": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz", - "integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==" - }, - "node_modules/@types/bson": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", - "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/meteor": { - "version": "1.4.70", - "resolved": "https://registry.npmjs.org/@types/meteor/-/meteor-1.4.70.tgz", - "integrity": "sha512-AefKGIqeTRKdUbceWJG973iTpCDuYyQYqrtTx8WBnesl+IprWVns9NB/sIpkX9P6z9ULFTFk5fy3CGUuVHlpYg==", - "dependencies": { - "@types/connect": "*", - "@types/mongodb": "*", - "@types/react": "*", - "@types/underscore": "*" - } - }, - "node_modules/@types/mongodb": { - "version": "3.6.12", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.12.tgz", - "integrity": "sha512-49aEzQD5VdHPxyd5dRyQdqEveAg9LanwrH8RQipnMuulwzKmODXIZRp0umtxi1eBUfEusRkoy8AVOMr+kVuFog==", - "dependencies": { - "@types/bson": "*", - "@types/node": "*" - } - }, - "node_modules/@types/node": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz", - "integrity": "sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==" - }, - "node_modules/@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" - }, - "node_modules/@types/react": { - "version": "16.14.6", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.6.tgz", - "integrity": "sha512-Ol/aFKune+P0FSFKIgf+XbhGzYGyz0p7g5befSt4rmbzfGLaZR0q7jPew9k7d3bvrcuaL8dPy9Oz3XGZmf9n+w==", - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/scheduler": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" - }, - "node_modules/@types/underscore": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.2.tgz", - "integrity": "sha512-Ls2ylbo7++ITrWk2Yc3G/jijwSq5V3GT0tlgVXEl2kKYXY3ImrtmTCoE2uyTWFRI5owMBriloZFWbE1SXOsE7w==" - }, - "node_modules/@types/yargs": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", - "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==" - }, - "node_modules/ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/chalk/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/chalk/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/chalk/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/chalk/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "node_modules/core-js-pure": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.12.1.tgz", - "integrity": "sha512-1cch+qads4JnDSWsvc7d6nzlKAippwjUlf6vykkTLW53VSV+NkE6muGBToAjEA8pG90cSfcud3JgVmW2ds5TaQ==" - }, - "node_modules/csstype": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", - "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" - }, - "node_modules/dom-accessibility-api": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz", - "integrity": "sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==" - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "engines": { - "node": ">=4" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", - "bin": { - "lz-string": "bin/bin.js" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", - "dependencies": { - "@jest/types": "^26.6.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-format/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/pretty-format/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, - "node_modules/react-test-renderer": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.14.0.tgz", - "integrity": "sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==", - "dependencies": { - "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "react-is": "^16.8.6", - "scheduler": "^0.19.1" - } - }, - "node_modules/react-test-renderer/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "node_modules/regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" - }, - "node_modules/scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "dependencies": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - } - }, + "lockfileVersion": 1, "dependencies": { "@babel/code-frame": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, "requires": { "@babel/highlight": "^7.12.13" } @@ -526,12 +15,14 @@ "@babel/helper-validator-identifier": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==" + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "dev": true }, "@babel/highlight": { "version": "7.14.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.14.0", "chalk": "^2.0.0", @@ -542,6 +33,7 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -554,6 +46,7 @@ "version": "7.14.0", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", + "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } @@ -562,6 +55,7 @@ "version": "7.14.0", "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.0.tgz", "integrity": "sha512-0R0HTZWHLk6G8jIk0FtoX+AatCtKnswS98VhXwGImFc759PJRp4Tru0PQYZofyijTFUr+gT8Mu7sgXVJLQ0ceg==", + "dev": true, "requires": { "core-js-pure": "^3.0.0", "regenerator-runtime": "^0.13.4" @@ -571,6 +65,7 @@ "version": "26.6.2", "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -583,6 +78,7 @@ "version": "7.31.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.0.tgz", "integrity": "sha512-0X7ACg4YvTRDFMIuTOEj6B4NpN7i3F/4j5igOcTI5NC5J+N4TribNdErCHOZF1LBWhhcyfwxelVwvoYNMUXTOA==", + "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -598,6 +94,7 @@ "version": "10.4.9", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-10.4.9.tgz", "integrity": "sha512-pHZKkqUy0tmiD81afs8xfiuseXfU/N7rAX3iKjeZYje86t9VaB0LrxYVa+OOsvkrveX5jCK3IjajVn2MbePvqA==", + "dev": true, "requires": { "@babel/runtime": "^7.10.3", "@testing-library/dom": "^7.22.3" @@ -606,12 +103,14 @@ "@types/aria-query": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz", - "integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==" + "integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==", + "dev": true }, "@types/bson": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==", + "dev": true, "requires": { "@types/node": "*" } @@ -620,6 +119,7 @@ "version": "3.4.34", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "dev": true, "requires": { "@types/node": "*" } @@ -627,12 +127,14 @@ "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", + "dev": true }, "@types/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, "requires": { "@types/istanbul-lib-coverage": "*" } @@ -641,6 +143,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, "requires": { "@types/istanbul-lib-report": "*" } @@ -649,6 +152,7 @@ "version": "1.4.70", "resolved": "https://registry.npmjs.org/@types/meteor/-/meteor-1.4.70.tgz", "integrity": "sha512-AefKGIqeTRKdUbceWJG973iTpCDuYyQYqrtTx8WBnesl+IprWVns9NB/sIpkX9P6z9ULFTFk5fy3CGUuVHlpYg==", + "dev": true, "requires": { "@types/connect": "*", "@types/mongodb": "*", @@ -660,6 +164,7 @@ "version": "3.6.12", "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.12.tgz", "integrity": "sha512-49aEzQD5VdHPxyd5dRyQdqEveAg9LanwrH8RQipnMuulwzKmODXIZRp0umtxi1eBUfEusRkoy8AVOMr+kVuFog==", + "dev": true, "requires": { "@types/bson": "*", "@types/node": "*" @@ -668,17 +173,20 @@ "@types/node": { "version": "15.0.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz", - "integrity": "sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==" + "integrity": "sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==", + "dev": true }, "@types/prop-types": { "version": "15.7.3", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==" + "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "dev": true }, "@types/react": { "version": "16.14.6", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.6.tgz", "integrity": "sha512-Ol/aFKune+P0FSFKIgf+XbhGzYGyz0p7g5befSt4rmbzfGLaZR0q7jPew9k7d3bvrcuaL8dPy9Oz3XGZmf9n+w==", + "dev": true, "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -688,17 +196,20 @@ "@types/scheduler": { "version": "0.16.1", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==" + "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==", + "dev": true }, "@types/underscore": { "version": "1.11.2", "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.2.tgz", - "integrity": "sha512-Ls2ylbo7++ITrWk2Yc3G/jijwSq5V3GT0tlgVXEl2kKYXY3ImrtmTCoE2uyTWFRI5owMBriloZFWbE1SXOsE7w==" + "integrity": "sha512-Ls2ylbo7++ITrWk2Yc3G/jijwSq5V3GT0tlgVXEl2kKYXY3ImrtmTCoE2uyTWFRI5owMBriloZFWbE1SXOsE7w==", + "dev": true }, "@types/yargs": { "version": "15.0.13", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", + "dev": true, "requires": { "@types/yargs-parser": "*" } @@ -706,17 +217,20 @@ "@types/yargs-parser": { "version": "20.2.0", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==" + "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "dev": true }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -725,6 +239,7 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, "requires": { "@babel/runtime": "^7.10.2", "@babel/runtime-corejs3": "^7.10.2" @@ -734,6 +249,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -743,6 +259,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -751,6 +268,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -758,17 +276,20 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -779,6 +300,7 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, "requires": { "color-name": "1.1.3" } @@ -786,47 +308,56 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true }, "core-js-pure": { "version": "3.12.1", "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.12.1.tgz", - "integrity": "sha512-1cch+qads4JnDSWsvc7d6nzlKAippwjUlf6vykkTLW53VSV+NkE6muGBToAjEA8pG90cSfcud3JgVmW2ds5TaQ==" + "integrity": "sha512-1cch+qads4JnDSWsvc7d6nzlKAippwjUlf6vykkTLW53VSV+NkE6muGBToAjEA8pG90cSfcud3JgVmW2ds5TaQ==", + "dev": true }, "csstype": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", - "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==" + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", + "dev": true }, "dom-accessibility-api": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz", - "integrity": "sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==" + "integrity": "sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==", + "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } @@ -834,17 +365,20 @@ "lz-string": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=" + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true }, "pretty-format": { "version": "26.6.2", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, "requires": { "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", @@ -856,6 +390,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -864,6 +399,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -871,7 +407,8 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true } } }, @@ -879,6 +416,7 @@ "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -888,7 +426,8 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true } } }, @@ -896,6 +435,7 @@ "version": "16.14.0", "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -906,6 +446,7 @@ "version": "16.14.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -916,12 +457,14 @@ "react-is": { "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true }, "react-test-renderer": { "version": "16.14.0", "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.14.0.tgz", "integrity": "sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==", + "dev": true, "requires": { "object-assign": "^4.1.1", "prop-types": "^15.6.2", @@ -932,19 +475,22 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true } } }, "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "dev": true }, "scheduler": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -954,6 +500,7 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "requires": { "has-flag": "^3.0.0" } diff --git a/packages/react-meteor-data/package.json b/packages/react-meteor-data/package.json index 67063b25..0b0a2efe 100644 --- a/packages/react-meteor-data/package.json +++ b/packages/react-meteor-data/package.json @@ -1,6 +1,6 @@ { "name": "react-meteor-data", - "dependencies": { + "devDependencies": { "@testing-library/react": "^10.4.9", "@types/meteor": "^1.4.70", "@types/react": "^16.14.6", From 9f0043c536d74a597a2b227e28c8583af715cdef Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Wed, 12 May 2021 00:47:37 -0400 Subject: [PATCH 04/16] Add useFind and useSubscribe --- packages/react-meteor-data/index.js | 2 + packages/react-meteor-data/useFind.ts | 124 +++++++++++++++++++++ packages/react-meteor-data/useSubscribe.ts | 28 +++++ packages/react-meteor-data/useTracker.ts | 2 +- 4 files changed, 155 insertions(+), 1 deletion(-) create mode 100644 packages/react-meteor-data/useFind.ts create mode 100644 packages/react-meteor-data/useSubscribe.ts diff --git a/packages/react-meteor-data/index.js b/packages/react-meteor-data/index.js index b79056b0..9b9b708f 100644 --- a/packages/react-meteor-data/index.js +++ b/packages/react-meteor-data/index.js @@ -10,3 +10,5 @@ if (Meteor.isDevelopment) { export { default as useTracker } from './useTracker'; export { default as withTracker } from './withTracker.tsx'; +export { useFind } from './useFind'; +export { useSubscribe } from './useSubscribe'; diff --git a/packages/react-meteor-data/useFind.ts b/packages/react-meteor-data/useFind.ts new file mode 100644 index 00000000..e25c9dcb --- /dev/null +++ b/packages/react-meteor-data/useFind.ts @@ -0,0 +1,124 @@ +import { Meteor } from 'meteor/meteor' +import { Mongo } from 'meteor/mongo' +import { useReducer, useMemo, useEffect, Reducer, DependencyList, useRef } from 'react' +import { Tracker } from 'meteor/tracker' + +type useFindActions = + | { type: 'refresh', data: T[] } + | { type: 'addedAt', document: T, atIndex: number } + | { type: 'changedAt', document: T, atIndex: number } + | { type: 'removedAt', atIndex: number } + | { type: 'movedTo', fromIndex: number, toIndex: number } + +const useFindReducer = (data: T[], action: useFindActions): T[] => { + switch (action.type) { + case 'refresh': + return action.data + case 'addedAt': + return [ + ...data.slice(0, action.atIndex), + action.document, + ...data.slice(action.atIndex) + ] + case 'changedAt': + return [ + ...data.slice(0, action.atIndex), + action.document, + ...data.slice(action.atIndex + 1) + ] + case 'removedAt': + return [ + ...data.slice(0, action.atIndex), + ...data.slice(action.atIndex + 1) + ] + case 'movedTo': + const doc = data[action.fromIndex] + const copy = [ + ...data.slice(0, action.fromIndex), + ...data.slice(action.fromIndex + 1) + ] + copy.splice(action.toIndex, 0, doc) + return copy + } +} + +const checkCursor = (cursor: Mongo.Cursor) => { + if (!(cursor instanceof Mongo.Cursor)) { + console.warn( + 'Warning: useFind requires an instance of Mongo.Cursor. ' + + 'Make sure you do NOT call .fetch() on your cursor.' + ); + } +} + +const useFindClient = (factory: () => Mongo.Cursor, deps: DependencyList) => { + let [data, dispatch] = useReducer>>( + useFindReducer, + [] + ) + + const { current: refs } = useRef<{ committed: Boolean, data: T[] }>({ committed: false, data: [] }) + + const cursor = useMemo(() => ( + // To avoid creating side effects in render, opt out + // of Tracker integration altogether. + Tracker.nonreactive(() => { + refs.committed = false + const c = factory() + if (Meteor.isDevelopment) { + checkCursor(c) + } + refs.data = c.fetch() + return c + }) + ), deps) + + useEffect(() => { + refs.committed = true + + // Refetch the data in case an update happened + // between first render and commit. Additionally, + // update in response to deps change. + const data = Tracker.nonreactive(() => cursor.fetch()) + + dispatch({ + type: 'refresh', + data: data + }) + + const observer = cursor.observe({ + addedAt (document, atIndex, before) { + dispatch({ type: 'addedAt', document, atIndex }) + }, + changedAt (newDocument, oldDocument, atIndex) { + dispatch({ type: 'changedAt', document: newDocument, atIndex }) + }, + removedAt (oldDocument, atIndex) { + dispatch({ type: 'removedAt', atIndex }) + }, + movedTo (document, fromIndex, toIndex, before) { + dispatch({ type: 'movedTo', fromIndex, toIndex }) + }, + // @ts-ignore + _suppress_initial: true + }) + + return () => { + observer.stop() + } + }, [cursor]) + + return !refs.committed ? refs.data : data +} + +const useFindServer = (factory: () => Mongo.Cursor, deps: DependencyList) => ( + Tracker.nonreactive(() => { + const cursor = factory() + if (Meteor.isDevelopment) checkCursor(cursor) + return cursor.fetch() + }) +) + +export const useFind = Meteor.isServer + ? useFindServer + : useFindClient diff --git a/packages/react-meteor-data/useSubscribe.ts b/packages/react-meteor-data/useSubscribe.ts new file mode 100644 index 00000000..1026d1ff --- /dev/null +++ b/packages/react-meteor-data/useSubscribe.ts @@ -0,0 +1,28 @@ +import { Meteor } from 'meteor/meteor' +import useTracker from './useTracker' + +const useSubscribeClient = (name?: string, ...args: any[]): () => boolean => { + let updateOnReady = false + let subscription: Meteor.SubscriptionHandle + + const isReady = useTracker(() => { + if (!name) return false + + subscription = Meteor.subscribe(name, ...args) + + return subscription.ready() + }, () => (!updateOnReady)) + + return () => { + updateOnReady = true + return !isReady + } +} + +const useSubscribeServer = (name?: string, ...args: any[]): () => boolean => ( + () => false +) + +export const useSubscribe = Meteor.isServer + ? useSubscribeServer + : useSubscribeClient diff --git a/packages/react-meteor-data/useTracker.ts b/packages/react-meteor-data/useTracker.ts index 33f816f5..e966aacc 100644 --- a/packages/react-meteor-data/useTracker.ts +++ b/packages/react-meteor-data/useTracker.ts @@ -32,7 +32,7 @@ const fur = (x: number): number => x + 1; const useForceUpdate = () => useReducer(fur, 0)[1]; export interface IReactiveFn { - (c?: Tracker.Computation): T + (c?: Tracker.Computation): T } export interface ISkipUpdate { From 8a31acb3f9842805e21640e1c0fe09ad1352068c Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Mon, 9 Aug 2021 23:21:57 -0400 Subject: [PATCH 05/16] Get the tests and readme started for useFind --- packages/react-meteor-data/.versions | 57 ---- packages/react-meteor-data/README.md | 53 ++++ packages/react-meteor-data/package-lock.json | 291 ++++++++---------- packages/react-meteor-data/package.json | 12 +- packages/react-meteor-data/tests.js | 1 + packages/react-meteor-data/useFind.tests.js | 73 +++++ packages/react-meteor-data/useFind.ts | 25 +- .../react-meteor-data/withTracker.tests.js | 1 - 8 files changed, 292 insertions(+), 221 deletions(-) delete mode 100644 packages/react-meteor-data/.versions create mode 100644 packages/react-meteor-data/useFind.tests.js diff --git a/packages/react-meteor-data/.versions b/packages/react-meteor-data/.versions deleted file mode 100644 index e1bf7b7d..00000000 --- a/packages/react-meteor-data/.versions +++ /dev/null @@ -1,57 +0,0 @@ -allow-deny@1.1.0 -babel-compiler@7.6.1 -babel-runtime@1.5.0 -base64@1.0.12 -binary-heap@1.0.11 -blaze@2.3.4 -boilerplate-generator@1.7.1 -callback-hook@1.3.0 -check@1.3.1 -ddp@1.4.0 -ddp-client@2.4.0 -ddp-common@1.4.0 -ddp-server@2.3.2 -deps@1.0.12 -diff-sequence@1.1.1 -dynamic-import@0.6.0 -ecmascript@0.15.1 -ecmascript-runtime@0.7.0 -ecmascript-runtime-client@0.11.0 -ecmascript-runtime-server@0.10.0 -ejson@1.1.1 -fetch@0.1.1 -geojson-utils@1.0.10 -htmljs@1.0.11 -id-map@1.1.0 -inter-process-messaging@0.1.1 -local-test:react-meteor-data@2.3.1 -logging@1.2.0 -meteor@1.9.3 -minimongo@1.6.2 -modern-browsers@0.1.5 -modules@0.16.0 -modules-runtime@0.12.0 -mongo@1.11.0 -mongo-decimal@0.1.2 -mongo-dev-server@1.1.0 -mongo-id@1.0.7 -npm-mongo@3.9.0 -observe-sequence@1.0.16 -ordered-dict@1.1.0 -promise@0.11.2 -random@1.2.0 -react-fast-refresh@0.1.0 -react-meteor-data@2.3.1 -reactive-dict@1.3.0 -reactive-var@1.0.11 -reload@1.3.1 -retry@1.1.0 -routepolicy@1.1.0 -socket-stream-client@0.3.1 -test-helpers@1.2.0 -tinytest@1.1.0 -tracker@1.2.0 -typescript@4.2.2 -underscore@1.0.10 -webapp@1.10.1 -webapp-hashing@1.1.0 diff --git a/packages/react-meteor-data/README.md b/packages/react-meteor-data/README.md index c2c6dd29..9495c451 100644 --- a/packages/react-meteor-data/README.md +++ b/packages/react-meteor-data/README.md @@ -231,6 +231,59 @@ export default withTracker({ })(Foo); ``` +#### `useFind(cursorFactory, deps)` Accellerate your lists + +The `useFind` hook can substantially speed up the rendering (and rerendering) of lists coming from mongo queries (subscriptions). It does this by providing highly tailored cursor management within the hook, using the `Cursor.observe` API, and carefully updating only the document object references changed during a DDP update. This approach allows a tighter use of core React tools and philosophies to turbo charge your list renders. It is a very different approach from the more general purpose approached used within `useTracker`, but it also requires a bit more set up. + +Here is an example in code: + +```jsx +import React, { memo } from 'react' +import { useFind } from 'meteor/react-meteor-data' +import TestDocs from '/imports/api/collections/TestDocs' + +// Memoize the list item +const MemoizedItem = memo(({doc}) => { + return ( +
  • {doc.id},{doc.updated}
  • + ) +}) + +const Test = () => { + const docs = useFind(() => TestDocs.find(), []) + return ( +
      + {docs.map(doc => + + )} +
    + ) +} + +// Later on, update a single document - notice only that single component is updated in the DOM +TestDocs.update({ id: 2 }, { $inc: { someProp: 1 } }) +``` + +#### `useSubscribe(subName, ...args)` A convenient wrapper for subscriptions + +`useSubscribe` is a convenient short hand for setting up subscriptions, particularly when working with `useFind`, which should NOT be used for setting up subs. At its core, it is a very simple wrapper around `useTracker` (with no deps) to create the subscription in a safe way, but allows you to avoid some of the cerimony around defining a factory and defining deps. Just pass the name of your subscription, and the arguments - don't worry about object refs, and off you go. + +It does have one super power - by default the `useSubscribe` hook sets up as little reactivity as possible, to keep unecessary rerenders to a minimum. But we still want to be able to check the "loading" state of the subscription. With a little cleverness applied, the hook will return a handle which can be invoked to opt in to reactive "ready" state updates: + +```jsx +// Note: isLoading is a function! +const isLoading = useSubscription('posts', groupId); +const posts = useFind(() => Posts.find({ groupId }), [groupId]); + +if (isLoading()) { + return +} else { + return
      + {posts.map(post =>
    • {post.title}
    • )} +
    +} +``` + ### Concurrent Mode, Suspense and Error Boundaries There are some additional considerations to keep in mind when using Concurrent Mode, Suspense and Error Boundaries, as each of these can cause React to cancel and discard (toss) a render, including the result of the first run of your reactive function. One of the things React developers often stress is that we should not create "side-effects" directly in the render method or in functional components. There are a number of good reasons for this, including allowing the React runtime to cancel renders. Limiting the use of side-effects allows features such as concurrent mode, suspense and error boundaries to work deterministically, without leaking memory or creating rogue processes. Care should be taken to avoid side effects in your reactive function for these reasons. (Note: this caution does not apply to Meteor specific side-effects like subscriptions, since those will be automatically cleaned up when `useTracker`'s computation is disposed.) diff --git a/packages/react-meteor-data/package-lock.json b/packages/react-meteor-data/package-lock.json index c4fe85cf..51802895 100644 --- a/packages/react-meteor-data/package-lock.json +++ b/packages/react-meteor-data/package-lock.json @@ -4,27 +4,27 @@ "lockfileVersion": 1, "dependencies": { "@babel/code-frame": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", - "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz", + "integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==", "dev": true, "requires": { - "@babel/highlight": "^7.12.13" + "@babel/highlight": "^7.14.5" } }, "@babel/helper-validator-identifier": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", - "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", + "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", "dev": true }, "@babel/highlight": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", - "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.5.tgz", + "integrity": "sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.0", + "@babel/helper-validator-identifier": "^7.14.5", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, @@ -43,41 +43,41 @@ } }, "@babel/runtime": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.0.tgz", - "integrity": "sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz", + "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/runtime-corejs3": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.0.tgz", - "integrity": "sha512-0R0HTZWHLk6G8jIk0FtoX+AatCtKnswS98VhXwGImFc759PJRp4Tru0PQYZofyijTFUr+gT8Mu7sgXVJLQ0ceg==", + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.9.tgz", + "integrity": "sha512-64RiH2ON4/y8qYtoa8rUiyam/tUVyGqRyNYhe+vCRGmjnV4bUlZvY+mwd0RrmLoCpJpdq3RsrNqKb7SJdw/4kw==", "dev": true, "requires": { - "core-js-pure": "^3.0.0", + "core-js-pure": "^3.16.0", "regenerator-runtime": "^0.13.4" } }, "@jest/types": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", - "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.0.6.tgz", + "integrity": "sha512-aSquT1qa9Pik26JK5/3rvnYb4bGtm1VFNesHKmNTwmPIgOrixvhL2ghIvFRNEpzy3gU+rUgjIF/KodbkFAl++g==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", - "@types/yargs": "^15.0.0", + "@types/yargs": "^16.0.0", "chalk": "^4.0.0" } }, "@testing-library/dom": { - "version": "7.31.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.31.0.tgz", - "integrity": "sha512-0X7ACg4YvTRDFMIuTOEj6B4NpN7i3F/4j5igOcTI5NC5J+N4TribNdErCHOZF1LBWhhcyfwxelVwvoYNMUXTOA==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.1.0.tgz", + "integrity": "sha512-kmW9alndr19qd6DABzQ978zKQ+J65gU2Rzkl8hriIetPnwpesRaK4//jEQyYh8fEALmGhomD/LBQqt+o+DL95Q==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", @@ -85,40 +85,40 @@ "@types/aria-query": "^4.2.0", "aria-query": "^4.2.2", "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.4", + "dom-accessibility-api": "^0.5.6", "lz-string": "^1.4.4", - "pretty-format": "^26.6.2" + "pretty-format": "^27.0.2" } }, "@testing-library/react": { - "version": "10.4.9", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-10.4.9.tgz", - "integrity": "sha512-pHZKkqUy0tmiD81afs8xfiuseXfU/N7rAX3iKjeZYje86t9VaB0LrxYVa+OOsvkrveX5jCK3IjajVn2MbePvqA==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.0.0.tgz", + "integrity": "sha512-sh3jhFgEshFyJ/0IxGltRhwZv2kFKfJ3fN1vTZ6hhMXzz9ZbbcTgmDYM4e+zJv+oiVKKEWZPyqPAh4MQBI65gA==", "dev": true, "requires": { - "@babel/runtime": "^7.10.3", - "@testing-library/dom": "^7.22.3" + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.0.0" } }, "@types/aria-query": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz", - "integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", "dev": true }, "@types/bson": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.3.tgz", - "integrity": "sha512-mVRvYnTOZJz3ccpxhr3wgxVmSeiYinW+zlzQz3SXWaJmD1DuL05Jeq7nKw3SnbKmbleW5qrLG5vdyWe/A9sXhw==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", + "integrity": "sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==", "dev": true, "requires": { "@types/node": "*" } }, "@types/connect": { - "version": "3.4.34", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.34.tgz", - "integrity": "sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==", + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", "dev": true, "requires": { "@types/node": "*" @@ -140,30 +140,40 @@ } }, "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", "dev": true, "requires": { "@types/istanbul-lib-report": "*" } }, + "@types/jquery": { + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.6.tgz", + "integrity": "sha512-SmgCQRzGPId4MZQKDj9Hqc6kSXFNWZFHpELkyK8AQhf8Zr6HKfCzFv9ZC1Fv3FyQttJZOlap3qYb12h61iZAIg==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, "@types/meteor": { - "version": "1.4.70", - "resolved": "https://registry.npmjs.org/@types/meteor/-/meteor-1.4.70.tgz", - "integrity": "sha512-AefKGIqeTRKdUbceWJG973iTpCDuYyQYqrtTx8WBnesl+IprWVns9NB/sIpkX9P6z9ULFTFk5fy3CGUuVHlpYg==", + "version": "1.4.76", + "resolved": "https://registry.npmjs.org/@types/meteor/-/meteor-1.4.76.tgz", + "integrity": "sha512-Hnem5BtouhbEP+6zS8wHy5TowL13m72jKVL2dZr/KwbNWpEihTUOsFjhRo88fjRaukhJjxwCB5hEFtAx5edS9g==", "dev": true, "requires": { "@types/connect": "*", - "@types/mongodb": "*", + "@types/jquery": "*", + "@types/mongodb": "^3.6.20", "@types/react": "*", "@types/underscore": "*" } }, "@types/mongodb": { - "version": "3.6.12", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.12.tgz", - "integrity": "sha512-49aEzQD5VdHPxyd5dRyQdqEveAg9LanwrH8RQipnMuulwzKmODXIZRp0umtxi1eBUfEusRkoy8AVOMr+kVuFog==", + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", + "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", "dev": true, "requires": { "@types/bson": "*", @@ -171,21 +181,21 @@ } }, "@types/node": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.0.2.tgz", - "integrity": "sha512-p68+a+KoxpoB47015IeYZYRrdqMUcpbK8re/zpFB8Ld46LHC1lPEbp3EXgkEhAYEcPvjJF6ZO+869SQ0aH1dcA==", + "version": "16.4.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.13.tgz", + "integrity": "sha512-bLL69sKtd25w7p1nvg9pigE4gtKVpGTPojBFLMkGHXuUgap2sLqQt2qUnqmVCDfzGUL0DRNZP+1prIZJbMeAXg==", "dev": true }, "@types/prop-types": { - "version": "15.7.3", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", - "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", "dev": true }, "@types/react": { - "version": "16.14.6", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.6.tgz", - "integrity": "sha512-Ol/aFKune+P0FSFKIgf+XbhGzYGyz0p7g5befSt4rmbzfGLaZR0q7jPew9k7d3bvrcuaL8dPy9Oz3XGZmf9n+w==", + "version": "17.0.16", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.16.tgz", + "integrity": "sha512-3kCUiOOlQTwUUvjNFkbBTWMTxdTGybz/PfjCw9JmaRGcEDBQh+nGMg7/E9P2rklhJuYVd25IYLNcvqgSPCPksg==", "dev": true, "requires": { "@types/prop-types": "*", @@ -194,30 +204,36 @@ } }, "@types/scheduler": { - "version": "0.16.1", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz", - "integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==", + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, + "@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", "dev": true }, "@types/underscore": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.2.tgz", - "integrity": "sha512-Ls2ylbo7++ITrWk2Yc3G/jijwSq5V3GT0tlgVXEl2kKYXY3ImrtmTCoE2uyTWFRI5owMBriloZFWbE1SXOsE7w==", + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.3.tgz", + "integrity": "sha512-Fl1TX1dapfXyDqFg2ic9M+vlXRktcPJrc4PR7sRc7sdVrjavg/JHlbUXBt8qWWqhJrmSqg3RNAkAPRiOYw6Ahw==", "dev": true }, "@types/yargs": { - "version": "15.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.13.tgz", - "integrity": "sha512-kQ5JNTrbDv3Rp5X2n/iUu37IJBDU2gsZ5R/g1/KHOOEc5IKfUFjXT6DENPGduh08I/pamwtEq4oul7gUqKTQDQ==", + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", "dev": true, "requires": { "@types/yargs-parser": "*" } }, "@types/yargs-parser": { - "version": "20.2.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.0.tgz", - "integrity": "sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==", + "version": "20.2.1", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz", + "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==", "dev": true }, "ansi-regex": { @@ -246,9 +262,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -312,9 +328,9 @@ "dev": true }, "core-js-pure": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.12.1.tgz", - "integrity": "sha512-1cch+qads4JnDSWsvc7d6nzlKAippwjUlf6vykkTLW53VSV+NkE6muGBToAjEA8pG90cSfcud3JgVmW2ds5TaQ==", + "version": "3.16.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.16.1.tgz", + "integrity": "sha512-TyofCdMzx0KMhi84mVRS8rL1XsRk2SPUNz2azmth53iRN0/08Uim9fdhQTaZTG1LqaXHYVci4RDHka6WrXfnvg==", "dev": true }, "csstype": { @@ -324,9 +340,9 @@ "dev": true }, "dom-accessibility-api": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz", - "integrity": "sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==", + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.7.tgz", + "integrity": "sha512-ml3lJIq9YjUfM9TUnEPvEYWFSwivwIGBPKpewX7tii7fwCazA8yCioGdqQcNsItPpfFvSJ3VIdMQPj60LJhcQA==", "dev": true }, "escape-string-regexp": { @@ -375,83 +391,44 @@ "dev": true }, "pretty-format": { - "version": "26.6.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", - "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "version": "27.0.6", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.0.6.tgz", + "integrity": "sha512-8tGD7gBIENgzqA+UBzObyWqQ5B778VIFZA/S66cclyd5YkFLYs2Js7gxDKf0MXtTc9zcS7t1xhdfcElJ3YIvkQ==", "dev": true, "requires": { - "@jest/types": "^26.6.2", + "@jest/types": "^27.0.6", "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", + "ansi-styles": "^5.0.0", "react-is": "^17.0.1" }, "dependencies": { "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", "dev": true } } }, "react": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", - "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", + "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", "dev": true, "requires": { "loose-envify": "^1.1.0", - "object-assign": "^4.1.1", - "prop-types": "^15.6.2" + "object-assign": "^4.1.1" } }, "react-dom": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", - "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", + "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "scheduler": "^0.19.1" + "scheduler": "^0.20.2" } }, "react-is": { @@ -460,36 +437,38 @@ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", "dev": true }, + "react-shallow-renderer": { + "version": "16.14.1", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz", + "integrity": "sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "react-is": "^16.12.0 || ^17.0.0" + } + }, "react-test-renderer": { - "version": "16.14.0", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.14.0.tgz", - "integrity": "sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==", + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz", + "integrity": "sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==", "dev": true, "requires": { "object-assign": "^4.1.1", - "prop-types": "^15.6.2", - "react-is": "^16.8.6", - "scheduler": "^0.19.1" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true - } + "react-is": "^17.0.2", + "react-shallow-renderer": "^16.13.1", + "scheduler": "^0.20.2" } }, "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", "dev": true }, "scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", + "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", "dev": true, "requires": { "loose-envify": "^1.1.0", diff --git a/packages/react-meteor-data/package.json b/packages/react-meteor-data/package.json index 0b0a2efe..fad69781 100644 --- a/packages/react-meteor-data/package.json +++ b/packages/react-meteor-data/package.json @@ -1,12 +1,12 @@ { "name": "react-meteor-data", "devDependencies": { - "@testing-library/react": "^10.4.9", - "@types/meteor": "^1.4.70", - "@types/react": "^16.14.6", + "@testing-library/react": "^12.0.0", + "@types/meteor": "^1.4.76", + "@types/react": "^17.0.16", "fast-deep-equal": "^3.1.3", - "react": "16.14.0", - "react-dom": "16.14.0", - "react-test-renderer": "16.14.0" + "react": "17.0.2", + "react-dom": "17.0.2", + "react-test-renderer": "17.0.2" } } diff --git a/packages/react-meteor-data/tests.js b/packages/react-meteor-data/tests.js index e444261a..4a6aab3a 100644 --- a/packages/react-meteor-data/tests.js +++ b/packages/react-meteor-data/tests.js @@ -1,2 +1,3 @@ import './useTracker.tests.js'; import './withTracker.tests.js'; +import './useFind.tests.js'; diff --git a/packages/react-meteor-data/useFind.tests.js b/packages/react-meteor-data/useFind.tests.js new file mode 100644 index 00000000..6d1d0518 --- /dev/null +++ b/packages/react-meteor-data/useFind.tests.js @@ -0,0 +1,73 @@ +/* global Meteor, Tinytest */ +import React, { memo } from 'react' +import ReactDOM from 'react-dom' +import { waitFor } from '@testing-library/react' +import { Mongo } from 'meteor/mongo' + +import { useFind } from './useFind' + +if (Meteor.isClient) { + Tinytest.addAsync('useFind - Verify reference stability between rerenders', async function (test, completed) { + const container = document.createElement("DIV") + + const TestDocs = new Mongo.Collection(null) + + TestDocs.insert({ + id: 0, + updated: 0 + }) + TestDocs.insert({ + id: 1, + updated: 0 + }) + TestDocs.insert({ + id: 2, + updated: 0 + }) + TestDocs.insert({ + id: 3, + updated: 0 + }) + TestDocs.insert({ + id: 4, + updated: 0 + }) + + let renders = 0 + const MemoizedItem = memo(({doc}) => { + renders++ + return ( +
  • {doc.id},{doc.updated}
  • + ) + }) + + const Test = () => { + const docs = useFind(() => TestDocs.find(), []) + return ( +
      + {docs.map(doc => + + )} +
    + ) + } + + ReactDOM.render(, container) + test.equal(renders, 5, '5 items should have rendered, only 5, no more.') + + await waitFor(() => {}, { container, timeout: 250 }) + + test.equal(renders, 10, '10 items should have rendered - the initial list is always tossed.') + + await waitFor(() => { + TestDocs.update({ id: 2 }, { $inc: { updated: 1 } }) + }, { container, timeout: 250 }) + + test.equal(renders, 11, '11 items should have rendered - only 1 of the items should have been matched by the reconciler after a single change.') + + completed() + }) + +} else { + +} diff --git a/packages/react-meteor-data/useFind.ts b/packages/react-meteor-data/useFind.ts index e25c9dcb..c0489302 100644 --- a/packages/react-meteor-data/useFind.ts +++ b/packages/react-meteor-data/useFind.ts @@ -51,7 +51,7 @@ const checkCursor = (cursor: Mongo.Cursor) => { } } -const useFindClient = (factory: () => Mongo.Cursor, deps: DependencyList) => { +const useFindClient = (factory: () => Mongo.Cursor, deps: DependencyList = []) => { let [data, dispatch] = useReducer>>( useFindReducer, [] @@ -122,3 +122,26 @@ const useFindServer = (factory: () => Mongo.Cursor, deps: Dependency export const useFind = Meteor.isServer ? useFindServer : useFindClient + +function useFindDev (reactiveFn, deps = null, skipUpdate = null) { + function warn (expects: string, pos: string, arg: string, type: string) { + console.warn( + `Warning: useFind expected a ${expects} in it\'s ${pos} argument ` + + `(${arg}), but got type of \`${type}\`.` + ); + } + + if (typeof reactiveFn !== 'function') { + warn("function", "1st", "reactiveFn", reactiveFn); + } + + if (!deps || !Array.isArray(deps)) { + warn("array", "2nd", "deps", typeof deps); + } + + return useFind(reactiveFn, deps); +} + +export default Meteor.isDevelopment + ? useFindDev as typeof useFindClient + : useFind; diff --git a/packages/react-meteor-data/withTracker.tests.js b/packages/react-meteor-data/withTracker.tests.js index faa3f156..5ffe1fba 100644 --- a/packages/react-meteor-data/withTracker.tests.js +++ b/packages/react-meteor-data/withTracker.tests.js @@ -36,7 +36,6 @@ if (Meteor.isClient) { }, skipUpdate: skipUpdate, })((props) => { - console.log(props) renders++; return {JSON.stringify(props.value)}; }); From 83c6dee1a73d91fa8fb48605ee13581591854f68 Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Thu, 30 Sep 2021 00:45:38 -0400 Subject: [PATCH 06/16] Implement and test null return value in useFind --- packages/react-meteor-data/useFind.tests.js | 43 ++++++++++++++++++++- packages/react-meteor-data/useFind.ts | 28 +++++++++----- 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/packages/react-meteor-data/useFind.tests.js b/packages/react-meteor-data/useFind.tests.js index 6d1d0518..7c8114c3 100644 --- a/packages/react-meteor-data/useFind.tests.js +++ b/packages/react-meteor-data/useFind.tests.js @@ -1,5 +1,5 @@ /* global Meteor, Tinytest */ -import React, { memo } from 'react' +import React, { memo, useState } from 'react' import ReactDOM from 'react-dom' import { waitFor } from '@testing-library/react' import { Mongo } from 'meteor/mongo' @@ -68,6 +68,47 @@ if (Meteor.isClient) { completed() }) + Tinytest.addAsync('useFind - null return is allowed', async function (test, completed) { + const container = document.createElement("DIV") + + const TestDocs = new Mongo.Collection(null) + + TestDocs.insert({ + id: 0, + updated: 0 + }) + + let setReturnNull, returnValue; + + const Test = () => { + const [returnNull, _setReturnNull] = useState(true) + setReturnNull = _setReturnNull + const docs = useFind(() => returnNull ? null : TestDocs.find(), [returnNull]) + returnValue = docs; + if (!docs) { + return null + } else { + return ( +
      + {docs.map(doc => +
    • + )} +
    + ) + } + } + + ReactDOM.render(, container) + test.isNull(returnValue, 'Return value should be null when the factory returns null') + + setReturnNull(false) + + await waitFor(() => {}, { container, timeout: 250 }) + test.isNotNull(returnValue, 'Return value should be null when the factory returns null') + + completed() + }) + } else { } diff --git a/packages/react-meteor-data/useFind.ts b/packages/react-meteor-data/useFind.ts index c0489302..c51235e8 100644 --- a/packages/react-meteor-data/useFind.ts +++ b/packages/react-meteor-data/useFind.ts @@ -42,8 +42,8 @@ const useFindReducer = (data: T[], action: useFindActions): T[] => { } } -const checkCursor = (cursor: Mongo.Cursor) => { - if (!(cursor instanceof Mongo.Cursor)) { +const checkCursor = (cursor: Mongo.Cursor | undefined | null) => { + if (cursor !== null && cursor !== undefined && !(cursor instanceof Mongo.Cursor)) { console.warn( 'Warning: useFind requires an instance of Mongo.Cursor. ' + 'Make sure you do NOT call .fetch() on your cursor.' @@ -51,30 +51,36 @@ const checkCursor = (cursor: Mongo.Cursor) => { } } -const useFindClient = (factory: () => Mongo.Cursor, deps: DependencyList = []) => { +const useFindClient = (factory: () => (Mongo.Cursor | undefined | null), deps: DependencyList = []) => { let [data, dispatch] = useReducer>>( useFindReducer, [] ) - const { current: refs } = useRef<{ committed: Boolean, data: T[] }>({ committed: false, data: [] }) + const { current: refs } = useRef<{ useReducerData: Boolean, data: T[] }>({ useReducerData: false, data: [] }) const cursor = useMemo(() => ( // To avoid creating side effects in render, opt out // of Tracker integration altogether. Tracker.nonreactive(() => { - refs.committed = false + refs.useReducerData = false const c = factory() if (Meteor.isDevelopment) { checkCursor(c) } - refs.data = c.fetch() + refs.data = (c instanceof Mongo.Cursor) + ? c.fetch() + : null return c }) ), deps) useEffect(() => { - refs.committed = true + refs.useReducerData = true + + if (!(cursor instanceof Mongo.Cursor)) { + return + } // Refetch the data in case an update happened // between first render and commit. Additionally, @@ -108,14 +114,16 @@ const useFindClient = (factory: () => Mongo.Cursor, deps: Dependency } }, [cursor]) - return !refs.committed ? refs.data : data + return refs.useReducerData ? data : refs.data } -const useFindServer = (factory: () => Mongo.Cursor, deps: DependencyList) => ( +const useFindServer = (factory: () => Mongo.Cursor | undefined | null, deps: DependencyList) => ( Tracker.nonreactive(() => { const cursor = factory() if (Meteor.isDevelopment) checkCursor(cursor) - return cursor.fetch() + return (cursor instanceof Mongo.Cursor) + ? cursor.fetch() + : null }) ) From 3fb997215ccfa0ab4a1750a6f1c91ed51ffcc278 Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Thu, 30 Sep 2021 00:59:06 -0400 Subject: [PATCH 07/16] Improve readme for useFind and useSubscribe --- packages/react-meteor-data/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-meteor-data/README.md b/packages/react-meteor-data/README.md index 9495c451..7735ed47 100644 --- a/packages/react-meteor-data/README.md +++ b/packages/react-meteor-data/README.md @@ -233,7 +233,7 @@ export default withTracker({ #### `useFind(cursorFactory, deps)` Accellerate your lists -The `useFind` hook can substantially speed up the rendering (and rerendering) of lists coming from mongo queries (subscriptions). It does this by providing highly tailored cursor management within the hook, using the `Cursor.observe` API, and carefully updating only the document object references changed during a DDP update. This approach allows a tighter use of core React tools and philosophies to turbo charge your list renders. It is a very different approach from the more general purpose approached used within `useTracker`, but it also requires a bit more set up. +The `useFind` hook can substantially speed up the rendering (and rerendering) of lists coming from mongo queries (subscriptions). It does this by providing highly tailored cursor management within the hook, using the `Cursor.observe` API, and carefully updating only the document object references changed during a DDP update. This approach allows a tighter use of core React tools and philosophies to turbo charge your list renders. It is a very different approach from the more general purpose `useTracker`, and it requires a bit more set up. Here is an example in code: @@ -266,9 +266,9 @@ TestDocs.update({ id: 2 }, { $inc: { someProp: 1 } }) #### `useSubscribe(subName, ...args)` A convenient wrapper for subscriptions -`useSubscribe` is a convenient short hand for setting up subscriptions, particularly when working with `useFind`, which should NOT be used for setting up subs. At its core, it is a very simple wrapper around `useTracker` (with no deps) to create the subscription in a safe way, but allows you to avoid some of the cerimony around defining a factory and defining deps. Just pass the name of your subscription, and the arguments - don't worry about object refs, and off you go. +`useSubscribe` is a convenient short hand for setting up a subscription. It is particularly useful when working with `useFind`, which should NOT be used for setting up subscriptions. At its core, it is a very simple wrapper around `useTracker` (with no deps) to create the subscription in a safe way, and allows you to avoid some of the cerimony around defining a factory and defining deps. Just pass the name of your subscription, and your arguments. No need to worry about object refs and deps. -It does have one super power - by default the `useSubscribe` hook sets up as little reactivity as possible, to keep unecessary rerenders to a minimum. But we still want to be able to check the "loading" state of the subscription. With a little cleverness applied, the hook will return a handle which can be invoked to opt in to reactive "ready" state updates: +`useSubscribe` returns an `isLoading` function. You can call that to react to changes in the subscription's loading state. This function will both return the loading state of the subscription, and enable a reactive update when the state changes. If you don't call this function, no re-render will occur when the state changes. ```jsx // Note: isLoading is a function! From 2ee7ccbfe98d7d1fb6f0822b985d0c0ccd1ae3a4 Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Thu, 30 Sep 2021 11:14:56 -0400 Subject: [PATCH 08/16] Remove superfluous .gitignore file --- packages/react-mongo/.gitignore | 1 - 1 file changed, 1 deletion(-) delete mode 100644 packages/react-mongo/.gitignore diff --git a/packages/react-mongo/.gitignore b/packages/react-mongo/.gitignore deleted file mode 100644 index b512c09d..00000000 --- a/packages/react-mongo/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules \ No newline at end of file From 36cd5a7b236bf00caeb241af76ed4c802de3eea4 Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Thu, 30 Sep 2021 11:20:25 -0400 Subject: [PATCH 09/16] Swap useSubscribe and useFind in the readme, and further improve --- packages/react-meteor-data/README.md | 42 ++++++++++++++-------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/packages/react-meteor-data/README.md b/packages/react-meteor-data/README.md index 7735ed47..a7320f7c 100644 --- a/packages/react-meteor-data/README.md +++ b/packages/react-meteor-data/README.md @@ -231,9 +231,29 @@ export default withTracker({ })(Foo); ``` +#### `useSubscribe(subName, ...args)` A convenient wrapper for subscriptions + +`useSubscribe` is a convenient short hand for setting up a subscription. It is particularly useful when working with `useFind`, which should NOT be used for setting up subscriptions. At its core, it is a very simple wrapper around `useTracker` (with no deps) to create the subscription in a safe way, and allows you to avoid some of the cerimony around defining a factory and defining deps. Just pass the name of your subscription, and your arguments. + +`useSubscribe` returns an `isLoading` function. You can call `isLoading()` to react to changes in the subscription's loading state. The `isLoading` function will both return the loading state of the subscription, and set up a reactivity for the loading state change. If you don't call this function, no re-render will occur when the loading state changes. + +```jsx +// Note: isLoading is a function! +const isLoading = useSubscription('posts', groupId); +const posts = useFind(() => Posts.find({ groupId }), [groupId]); + +if (isLoading()) { + return +} else { + return
      + {posts.map(post =>
    • {post.title}
    • )} +
    +} +``` + #### `useFind(cursorFactory, deps)` Accellerate your lists -The `useFind` hook can substantially speed up the rendering (and rerendering) of lists coming from mongo queries (subscriptions). It does this by providing highly tailored cursor management within the hook, using the `Cursor.observe` API, and carefully updating only the document object references changed during a DDP update. This approach allows a tighter use of core React tools and philosophies to turbo charge your list renders. It is a very different approach from the more general purpose `useTracker`, and it requires a bit more set up. +The `useFind` hook can substantially speed up the rendering (and rerendering) of lists coming from mongo queries (subscriptions). It does this by controlling document object references. By providing a highly tailored cursor management within the hook, using the `Cursor.observe` API, `useFind` carefully updates only the object references changed during a DDP update. This approach allows a tighter use of core React tools and philosophies to turbo charge your list renders. It is a very different approach from the more general purpose `useTracker`, and it requires a bit more set up. A notable differences is that you should NOT call `.fetch()`. `useFind` requires its factory to return a `Mongo.Cursor` object. You may also return `null`, if you want to conditionally set up the Cursor. Here is an example in code: @@ -264,26 +284,6 @@ const Test = () => { TestDocs.update({ id: 2 }, { $inc: { someProp: 1 } }) ``` -#### `useSubscribe(subName, ...args)` A convenient wrapper for subscriptions - -`useSubscribe` is a convenient short hand for setting up a subscription. It is particularly useful when working with `useFind`, which should NOT be used for setting up subscriptions. At its core, it is a very simple wrapper around `useTracker` (with no deps) to create the subscription in a safe way, and allows you to avoid some of the cerimony around defining a factory and defining deps. Just pass the name of your subscription, and your arguments. No need to worry about object refs and deps. - -`useSubscribe` returns an `isLoading` function. You can call that to react to changes in the subscription's loading state. This function will both return the loading state of the subscription, and enable a reactive update when the state changes. If you don't call this function, no re-render will occur when the state changes. - -```jsx -// Note: isLoading is a function! -const isLoading = useSubscription('posts', groupId); -const posts = useFind(() => Posts.find({ groupId }), [groupId]); - -if (isLoading()) { - return -} else { - return
      - {posts.map(post =>
    • {post.title}
    • )} -
    -} -``` - ### Concurrent Mode, Suspense and Error Boundaries There are some additional considerations to keep in mind when using Concurrent Mode, Suspense and Error Boundaries, as each of these can cause React to cancel and discard (toss) a render, including the result of the first run of your reactive function. One of the things React developers often stress is that we should not create "side-effects" directly in the render method or in functional components. There are a number of good reasons for this, including allowing the React runtime to cancel renders. Limiting the use of side-effects allows features such as concurrent mode, suspense and error boundaries to work deterministically, without leaking memory or creating rogue processes. Care should be taken to avoid side effects in your reactive function for these reasons. (Note: this caution does not apply to Meteor specific side-effects like subscriptions, since those will be automatically cleaned up when `useTracker`'s computation is disposed.) From d40b2181f8cbb74dfc1cc74795a786d8133981fa Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Tue, 5 Oct 2021 03:07:17 -0400 Subject: [PATCH 10/16] Document the null return option --- packages/react-meteor-data/README.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/react-meteor-data/README.md b/packages/react-meteor-data/README.md index a7320f7c..0f09ce83 100644 --- a/packages/react-meteor-data/README.md +++ b/packages/react-meteor-data/README.md @@ -263,7 +263,7 @@ import { useFind } from 'meteor/react-meteor-data' import TestDocs from '/imports/api/collections/TestDocs' // Memoize the list item -const MemoizedItem = memo(({doc}) => { +const ListItem = memo(({doc}) => { return (
  • {doc.id},{doc.updated}
  • ) @@ -274,7 +274,7 @@ const Test = () => { return (
      {docs.map(doc => - + )}
    ) @@ -284,6 +284,17 @@ const Test = () => { TestDocs.update({ id: 2 }, { $inc: { someProp: 1 } }) ``` +If you want to conditionally call the find method based on some props configuration or anything else, return `null` from the factory. + +```jsx +const docs = useFind(() => { + if (props.skip) { + return null + } + return TestDocs.find() +}, []) +``` + ### Concurrent Mode, Suspense and Error Boundaries There are some additional considerations to keep in mind when using Concurrent Mode, Suspense and Error Boundaries, as each of these can cause React to cancel and discard (toss) a render, including the result of the first run of your reactive function. One of the things React developers often stress is that we should not create "side-effects" directly in the render method or in functional components. There are a number of good reasons for this, including allowing the React runtime to cancel renders. Limiting the use of side-effects allows features such as concurrent mode, suspense and error boundaries to work deterministically, without leaking memory or creating rogue processes. Care should be taken to avoid side effects in your reactive function for these reasons. (Note: this caution does not apply to Meteor specific side-effects like subscriptions, since those will be automatically cleaned up when `useTracker`'s computation is disposed.) From 5587b2e1fe6bfb4e17cc4ec78a89be5e84e141c0 Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Tue, 12 Oct 2021 01:48:08 -0400 Subject: [PATCH 11/16] Fix typedef and default val for deps in useFindDev --- packages/react-meteor-data/useFind.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/react-meteor-data/useFind.ts b/packages/react-meteor-data/useFind.ts index c51235e8..2d0b156a 100644 --- a/packages/react-meteor-data/useFind.ts +++ b/packages/react-meteor-data/useFind.ts @@ -131,7 +131,7 @@ export const useFind = Meteor.isServer ? useFindServer : useFindClient -function useFindDev (reactiveFn, deps = null, skipUpdate = null) { +function useFindDev (factory: () => (Mongo.Cursor | undefined | null), deps: DependencyList = []) { function warn (expects: string, pos: string, arg: string, type: string) { console.warn( `Warning: useFind expected a ${expects} in it\'s ${pos} argument ` @@ -139,17 +139,17 @@ function useFindDev (reactiveFn, deps = null, skipUpdate = null) { ); } - if (typeof reactiveFn !== 'function') { - warn("function", "1st", "reactiveFn", reactiveFn); + if (typeof factory !== 'function') { + warn("function", "1st", "reactiveFn", factory); } if (!deps || !Array.isArray(deps)) { warn("array", "2nd", "deps", typeof deps); } - return useFind(reactiveFn, deps); + return useFind(factory, deps); } export default Meteor.isDevelopment - ? useFindDev as typeof useFindClient + ? useFindDev : useFind; From fc5316b8a9f762fbe450c7aeef7c13cb07de0fdd Mon Sep 17 00:00:00 2001 From: Jan Dvorak Date: Wed, 20 Oct 2021 17:24:47 +0200 Subject: [PATCH 12/16] Published react-meteor-data@2.4.0-beta.1 --- packages/react-meteor-data/.versions | 56 +++++++++++++++++++++++++ packages/react-meteor-data/CHANGELOG.md | 3 ++ packages/react-meteor-data/package.js | 2 +- 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 packages/react-meteor-data/.versions diff --git a/packages/react-meteor-data/.versions b/packages/react-meteor-data/.versions new file mode 100644 index 00000000..586e96e7 --- /dev/null +++ b/packages/react-meteor-data/.versions @@ -0,0 +1,56 @@ +allow-deny@1.1.0 +babel-compiler@7.7.0 +babel-runtime@1.5.0 +base64@1.0.12 +binary-heap@1.0.11 +blaze@2.5.0 +boilerplate-generator@1.7.1 +callback-hook@1.4.0 +check@1.3.1 +ddp@1.4.0 +ddp-client@2.5.0 +ddp-common@1.4.0 +ddp-server@2.5.0 +diff-sequence@1.1.1 +dynamic-import@0.7.2 +ecmascript@0.15.3 +ecmascript-runtime@0.8.0 +ecmascript-runtime-client@0.12.1 +ecmascript-runtime-server@0.11.0 +ejson@1.1.1 +fetch@0.1.1 +geojson-utils@1.0.10 +htmljs@1.1.1 +id-map@1.1.1 +inter-process-messaging@0.1.1 +local-test:react-meteor-data@2.4.0-beta.1 +logging@1.3.1 +meteor@1.10.0 +minimongo@1.7.0 +modern-browsers@0.1.7 +modules@0.17.0 +modules-runtime@0.12.0 +mongo@1.13.0 +mongo-decimal@0.1.2 +mongo-dev-server@1.1.0 +mongo-id@1.0.8 +npm-mongo@3.9.1 +observe-sequence@1.0.19 +ordered-dict@1.1.0 +promise@0.12.0 +random@1.2.0 +react-fast-refresh@0.1.1 +react-meteor-data@2.4.0-beta.1 +reactive-dict@1.3.0 +reactive-var@1.0.11 +reload@1.3.1 +retry@1.1.0 +routepolicy@1.1.1 +socket-stream-client@0.4.0 +test-helpers@1.3.0 +tinytest@1.2.0 +tracker@1.2.0 +typescript@4.3.5 +underscore@1.0.10 +webapp@1.12.0 +webapp-hashing@1.1.0 diff --git a/packages/react-meteor-data/CHANGELOG.md b/packages/react-meteor-data/CHANGELOG.md index acb8baea..e0a37b67 100644 --- a/packages/react-meteor-data/CHANGELOG.md +++ b/packages/react-meteor-data/CHANGELOG.md @@ -1,4 +1,7 @@ # CHANGELOG +## v2.4.0, 2021-10- +* Added `useSubscribe` and `useFind` hooks + ## v2.3.3, 2021-07-14 * Fixes a publication issue in v2.3.2 diff --git a/packages/react-meteor-data/package.js b/packages/react-meteor-data/package.js index c72e0902..736b8380 100644 --- a/packages/react-meteor-data/package.js +++ b/packages/react-meteor-data/package.js @@ -3,7 +3,7 @@ Package.describe({ name: 'react-meteor-data', summary: 'React hook for reactively tracking Meteor data', - version: '2.3.3', + version: '2.4.0-beta.1', documentation: 'README.md', git: 'https://github.com/meteor/react-packages', }); From 05e3edf25168b3d2611a903fc0d41e54a6fc01e1 Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Wed, 20 Oct 2021 18:45:05 -0400 Subject: [PATCH 13/16] Add a note about conditionally calling useSubscribe to readme --- packages/react-meteor-data/README.md | 11 ++++++++++- packages/react-meteor-data/useSubscribe.ts | 2 +- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/react-meteor-data/README.md b/packages/react-meteor-data/README.md index 0f09ce83..04857ebc 100644 --- a/packages/react-meteor-data/README.md +++ b/packages/react-meteor-data/README.md @@ -239,7 +239,7 @@ export default withTracker({ ```jsx // Note: isLoading is a function! -const isLoading = useSubscription('posts', groupId); +const isLoading = useSubscribe('posts', groupId); const posts = useFind(() => Posts.find({ groupId }), [groupId]); if (isLoading()) { @@ -251,6 +251,15 @@ if (isLoading()) { } ``` +If you want to conditionally subscribe, you can set the `name` field (the first argument) to a falsy value to bypass the subscription. + +```jsx +const needsData = false; +const isLoading = useSubscribe(needsData ? "my-pub" : null); + +// When a subscription is not used, isLoading() will always return false +``` + #### `useFind(cursorFactory, deps)` Accellerate your lists The `useFind` hook can substantially speed up the rendering (and rerendering) of lists coming from mongo queries (subscriptions). It does this by controlling document object references. By providing a highly tailored cursor management within the hook, using the `Cursor.observe` API, `useFind` carefully updates only the object references changed during a DDP update. This approach allows a tighter use of core React tools and philosophies to turbo charge your list renders. It is a very different approach from the more general purpose `useTracker`, and it requires a bit more set up. A notable differences is that you should NOT call `.fetch()`. `useFind` requires its factory to return a `Mongo.Cursor` object. You may also return `null`, if you want to conditionally set up the Cursor. diff --git a/packages/react-meteor-data/useSubscribe.ts b/packages/react-meteor-data/useSubscribe.ts index 1026d1ff..6fdae732 100644 --- a/packages/react-meteor-data/useSubscribe.ts +++ b/packages/react-meteor-data/useSubscribe.ts @@ -6,7 +6,7 @@ const useSubscribeClient = (name?: string, ...args: any[]): () => boolean => { let subscription: Meteor.SubscriptionHandle const isReady = useTracker(() => { - if (!name) return false + if (!name) return true subscription = Meteor.subscribe(name, ...args) From f890b992c4a18b9722c8f1ea8b557920b2439582 Mon Sep 17 00:00:00 2001 From: Kevin Newman Date: Fri, 29 Oct 2021 13:12:16 -0400 Subject: [PATCH 14/16] Ensure the initial render computation is always stopped before the permanent one is created in useTracker. --- packages/react-meteor-data/useTracker.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/react-meteor-data/useTracker.ts b/packages/react-meteor-data/useTracker.ts index e966aacc..e48d89aa 100644 --- a/packages/react-meteor-data/useTracker.ts +++ b/packages/react-meteor-data/useTracker.ts @@ -120,6 +120,7 @@ const useTrackerWithDeps = (reactiveFn: IReactiveFn, deps: Dependenc const { current: refs } = useRef<{ reactiveFn: IReactiveFn; data?: T; + comp?: Tracker.Computation; }>({ reactiveFn }); // keep reactiveFn ref fresh @@ -133,11 +134,24 @@ const useTrackerWithDeps = (reactiveFn: IReactiveFn, deps: Dependenc refs.data = refs.reactiveFn(); }) ); + // In some cases, the useEffect hook will run before Meteor.defer, such as + // when React.lazy is used. This will allow it to be stopped earlier in + // useEffect if needed. + refs.comp = comp; // To avoid creating side effects in render, stop the computation immediately - Meteor.defer(() => { comp.stop() }); + Meteor.defer(() => { + if (refs.comp) { + refs.comp.stop(); + delete refs.comp; + } + }); }, deps); useEffect(() => { + if (refs.comp) { + refs.comp.stop(); + delete refs.comp; + } const computation = Tracker.nonreactive( () => Tracker.autorun((c) => { const data: T = refs.reactiveFn(c); From 4abe2117809a6ae040b50766d36bc20bd131af92 Mon Sep 17 00:00:00 2001 From: Jan Dvorak Date: Sun, 31 Oct 2021 10:44:57 +0100 Subject: [PATCH 15/16] Bump for 2.4-beta.2 Prepare for 2.4-beta.2 release. --- packages/react-meteor-data/.versions | 4 ++-- packages/react-meteor-data/package.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react-meteor-data/.versions b/packages/react-meteor-data/.versions index 586e96e7..bf9a1222 100644 --- a/packages/react-meteor-data/.versions +++ b/packages/react-meteor-data/.versions @@ -23,7 +23,7 @@ geojson-utils@1.0.10 htmljs@1.1.1 id-map@1.1.1 inter-process-messaging@0.1.1 -local-test:react-meteor-data@2.4.0-beta.1 +local-test:react-meteor-data@2.4.0-beta.2 logging@1.3.1 meteor@1.10.0 minimongo@1.7.0 @@ -40,7 +40,7 @@ ordered-dict@1.1.0 promise@0.12.0 random@1.2.0 react-fast-refresh@0.1.1 -react-meteor-data@2.4.0-beta.1 +react-meteor-data@2.4.0-beta.2 reactive-dict@1.3.0 reactive-var@1.0.11 reload@1.3.1 diff --git a/packages/react-meteor-data/package.js b/packages/react-meteor-data/package.js index 736b8380..46980a4f 100644 --- a/packages/react-meteor-data/package.js +++ b/packages/react-meteor-data/package.js @@ -3,7 +3,7 @@ Package.describe({ name: 'react-meteor-data', summary: 'React hook for reactively tracking Meteor data', - version: '2.4.0-beta.1', + version: '2.4.0-beta.2', documentation: 'README.md', git: 'https://github.com/meteor/react-packages', }); From 472d5baa13ab136eb02b3a0fe9328a952c78068c Mon Sep 17 00:00:00 2001 From: filipenevola Date: Thu, 2 Dec 2021 20:33:29 -0400 Subject: [PATCH 16/16] v2.4.0 --- packages/react-meteor-data/.versions | 12 ++++++------ packages/react-meteor-data/CHANGELOG.md | 2 +- packages/react-meteor-data/README.md | 2 +- packages/react-meteor-data/package.js | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/react-meteor-data/.versions b/packages/react-meteor-data/.versions index bf9a1222..0bbed27b 100644 --- a/packages/react-meteor-data/.versions +++ b/packages/react-meteor-data/.versions @@ -13,7 +13,7 @@ ddp-common@1.4.0 ddp-server@2.5.0 diff-sequence@1.1.1 dynamic-import@0.7.2 -ecmascript@0.15.3 +ecmascript@0.16.0 ecmascript-runtime@0.8.0 ecmascript-runtime-client@0.12.1 ecmascript-runtime-server@0.11.0 @@ -23,7 +23,7 @@ geojson-utils@1.0.10 htmljs@1.1.1 id-map@1.1.1 inter-process-messaging@0.1.1 -local-test:react-meteor-data@2.4.0-beta.2 +local-test:react-meteor-data@2.4.0 logging@1.3.1 meteor@1.10.0 minimongo@1.7.0 @@ -39,8 +39,8 @@ observe-sequence@1.0.19 ordered-dict@1.1.0 promise@0.12.0 random@1.2.0 -react-fast-refresh@0.1.1 -react-meteor-data@2.4.0-beta.2 +react-fast-refresh@0.2.0 +react-meteor-data@2.4.0 reactive-dict@1.3.0 reactive-var@1.0.11 reload@1.3.1 @@ -50,7 +50,7 @@ socket-stream-client@0.4.0 test-helpers@1.3.0 tinytest@1.2.0 tracker@1.2.0 -typescript@4.3.5 +typescript@4.4.0 underscore@1.0.10 -webapp@1.12.0 +webapp@1.13.0 webapp-hashing@1.1.0 diff --git a/packages/react-meteor-data/CHANGELOG.md b/packages/react-meteor-data/CHANGELOG.md index e0a37b67..0ff81ad4 100644 --- a/packages/react-meteor-data/CHANGELOG.md +++ b/packages/react-meteor-data/CHANGELOG.md @@ -1,5 +1,5 @@ # CHANGELOG -## v2.4.0, 2021-10- +## v2.4.0, 2021-12-02 * Added `useSubscribe` and `useFind` hooks ## v2.3.3, 2021-07-14 diff --git a/packages/react-meteor-data/README.md b/packages/react-meteor-data/README.md index 04857ebc..425269c1 100644 --- a/packages/react-meteor-data/README.md +++ b/packages/react-meteor-data/README.md @@ -262,7 +262,7 @@ const isLoading = useSubscribe(needsData ? "my-pub" : null); #### `useFind(cursorFactory, deps)` Accellerate your lists -The `useFind` hook can substantially speed up the rendering (and rerendering) of lists coming from mongo queries (subscriptions). It does this by controlling document object references. By providing a highly tailored cursor management within the hook, using the `Cursor.observe` API, `useFind` carefully updates only the object references changed during a DDP update. This approach allows a tighter use of core React tools and philosophies to turbo charge your list renders. It is a very different approach from the more general purpose `useTracker`, and it requires a bit more set up. A notable differences is that you should NOT call `.fetch()`. `useFind` requires its factory to return a `Mongo.Cursor` object. You may also return `null`, if you want to conditionally set up the Cursor. +The `useFind` hook can substantially speed up the rendering (and rerendering) of lists coming from mongo queries (subscriptions). It does this by controlling document object references. By providing a highly tailored cursor management within the hook, using the `Cursor.observe` API, `useFind` carefully updates only the object references changed during a DDP update. This approach allows a tighter use of core React tools and philosophies to turbo charge your list renders. It is a very different approach from the more general purpose `useTracker`, and it requires a bit more set up. A notable difference is that you should NOT call `.fetch()`. `useFind` requires its factory to return a `Mongo.Cursor` object. You may also return `null`, if you want to conditionally set up the Cursor. Here is an example in code: diff --git a/packages/react-meteor-data/package.js b/packages/react-meteor-data/package.js index 46980a4f..e9342dc7 100644 --- a/packages/react-meteor-data/package.js +++ b/packages/react-meteor-data/package.js @@ -3,7 +3,7 @@ Package.describe({ name: 'react-meteor-data', summary: 'React hook for reactively tracking Meteor data', - version: '2.4.0-beta.2', + version: '2.4.0', documentation: 'README.md', git: 'https://github.com/meteor/react-packages', });