Merge branch 'devel' into backport-faster-babel-parcing

This commit is contained in:
Jan Dvorak
2023-11-10 14:41:34 +01:00
committed by GitHub
4 changed files with 39 additions and 40 deletions

View File

@@ -346,3 +346,7 @@ of legitimate users by attempting all possible passwords.
These rate limiting rules can be removed by calling
`Accounts.removeDefaultRateLimit()`. Please see the
[`DDPRateLimiter`](#ddpratelimiter) docs for more information.
{% apibox "AccountsServer#addDefaultRateLimit" %}
{% apibox "AccountsServer#removeDefaultRateLimit" %}

View File

@@ -81,45 +81,33 @@ is automatically stopped and won't be rerun.
### Tracker.autorun and async callbacks
`Tracker.autorun` can accept an `async` callback function.
However, to make the async call reactive, you should wrap your async function in
a `Tracker.withComputation` call.
```javascript
Tracker.autorun(async function example1(computation) {
let asyncData = await asyncDataFunction();
let users =
await Tracker.withComputation(computation, () => Meteor.users.find({}).fetch());
});
```
> If you want to get computation in other way you can use `Tracker.currentComputation`
To preserve reactivity for the reactive variables inside the async callback function, you must use a `Tracker.withComputation` call as described below:
{% apibox "Tracker.withComputation" %}
In general, the rules to use `Tracker.withComputation` like this:
1. `async` function *before the first* `await` if just like a sync one.
2. `async` function *after the first* `await` looses the `Tracker.currentComputation`
but it can be restored using `Tracker.withComputation`, *but only within the callback*.
If you have for example:
```javascript
Tracker.autorun(async function (computation) {
let asyncData = await someAsyncCall();
let links = await LinksCollection.find({}).fetch();
// code above will not trigger reruns.
Tracker.autorun(async function example1(computation) {
// Code before the first await will stay reactive.
reactiveVar1.get(); // This will trigger a rerun.
let links = await LinksCollection.findAsync({}).fetch(); // First async call will stay reactive.
// Code after the first await looses Tracker.currentComputation: no reactivity.
reactiveVar2.get(); // This won't trigger a rerun.
// You can bring back reactivity with the Tracker.withCompuation wrapper:
let users = await Tracker.withComputation(computation, () => Meteor.users.findAsync({}).fetch());
// Code below will again not be reactive, so you will need another Tracker.withComputation.
const value = Tracker.withComputation(computation, () => reactiveVar3.get()); // This will trigger a rerun.
});
```
You can make this example reactive by wrapping the `Meteor.users.find` call in a `Tracker.withComputation` call:
```javascript
Tracker.autorun(async function (computation) {
let asyncData = await someAsyncCall();
let users =
await Tracker.withComputation(computation, () => Meteor.users.find({}).fetch());
// code above will trigger reruns.
});
```
As a rule of thumb, you are okay with wrapping all reactive statements inside a `Tracker.withComputation` to preserve current computation.
But it comes at a performance cost - it should be used only where needed.
Reason behind is, that an await implicitly *"moves"* the code below in a Promise resolved function. When this function runs (after it has been fetched from the micro task queue), `Tracker.withComputation` preserves the reference to the computation of the `Tracker.autorun`.
The `react-meteor-data` package uses `Tracker.withComputation` to make the `useTracker` accept async callbacks.
More can be seen [here](https://github.com/meteor/react-packages/tree/master/packages/react-meteor-data#maintaining-the-reactive-context)

View File

@@ -1364,15 +1364,23 @@ export class AccountsServer extends AccountsCommon {
}
};
// Removes default rate limiting rule
/**
* @summary Removes default rate limiting rule
* @locus Server
* @importFromPackage accounts-base
*/
removeDefaultRateLimit() {
const resp = DDPRateLimiter.removeRule(this.defaultRateLimiterRuleId);
this.defaultRateLimiterRuleId = null;
return resp;
};
// Add a default rule of limiting logins, creating new users and password reset
// to 5 times every 10 seconds per connection.
/**
* @summary Add a default rule of limiting logins, creating new users and password reset
* to 5 times every 10 seconds per connection.
* @locus Server
* @importFromPackage accounts-base
*/
addDefaultRateLimit() {
if (!this.defaultRateLimiterRuleId) {
this.defaultRateLimiterRuleId = DDPRateLimiter.addRule({

View File

@@ -50,7 +50,7 @@ The current temperature is 71.9 F (printed a few minutes later)
The function passed to `Tracker.autorun` is called once immediately, and then it's called again whenever there are any changes to any of the _reactive data sources_ that it referenced. To make this work, `currentTemperatureCelsius` just needs to register with Tracker as a reactive data source when it's called, which takes only a few lines of code.
Or, instead of calling `Tracker.autorun` ourselves, we might use `currentTemperatureFahrenheit` in a [Blaze](https://www.meteor.com/blaze) template:
Or, instead of calling `Tracker.autorun` ourselves, we might use `currentTemperatureFahrenheit` in a [Blaze](https://www.blazejs.org/) template:
```handlebars
<!-- In demo.html -->
@@ -100,9 +100,9 @@ It's easy for a library to detect if Tracker is available, and cooperate with it
The Meteor project provides a variety of Tracker-aware libraries:
- [Blaze](https://www.meteor.com/blaze) is a reactive templating/DOM update library designed to work well with Tracker.
- [Blaze](https://www.blazejs.org/) is a reactive templating/DOM update library designed to work well with Tracker.
- [Minimongo](https://www.meteor.com/mini-databases) is a Tracker-aware reimplementation of the MongoDB API in JavaScript, very useful for storing and querying client-side data. We also have a ["full stack database driver"](https://www.meteor.com/full-stack-db-drivers) for Mongo that replicates data from a real server-side MongoDB database into Minimongo.
- [Minimongo](https://github.com/meteor/meteor/tree/devel/packages/minimongo) is a Tracker-aware reimplementation of the MongoDB API in JavaScript, very useful for storing and querying client-side data. We also have a ["full stack database driver"](https://docs.meteor.com/api/collections.html#Mongo-Collection) for Mongo that replicates data from a real server-side MongoDB database into Minimongo.
- [reactive-dict](https://atmospherejs.com/meteor/reactive-dict), and
[reactive-var](https://atmospherejs.com/meteor/reactive-var) provide
@@ -113,7 +113,7 @@ code.
- Other Meteor core packages are generally Tracker-aware wherever it
makes sense. For example, the current connection status is reactive
in Meteor's [DDP](https://www.meteor.com/ddp) implementation, and
in Meteor's [DDP](https://github.com/meteor/meteor/tree/devel/packages/ddp) implementation, and
the currently logged in user is reactive in [Meteor
Accounts](https://docs.meteor.com/api/accounts) system.
@@ -126,4 +126,3 @@ Ideas for future work include:
- Providing a contract for _settable_ reactive values, to make it easier to build bidirectionally bound forms. There is some discussion of this [here](https://meteor.hackpad.com/Lickable-Forms-and-Components-6CVspZsVwJY).
- Making it possible to control invalidation order, for example by specifying that if autorun B was created inside autorun A, then if both A and B are invalidated and eligible to be rerun, then A will rerun before B. It is easy to construct theoretical situations where this would be valuable, but situations where this makes a difference in real apps seem to be surprisingly rare.
Also as described on the project pages for [Mini databases](https://www.meteor.com/mini-databases) and [Full stack database drivers](https://www.meteor.com/full-stack-db-drivers), the Meteor project intends to eventually sponsor development of Tracker-aware libraries that emulate other server-side databases besides Mongo.