How did I migrate our app to new Async API (Meteor 2.8+)

@rjdavid - Yeah, that makes sense.

We specifically always call our Mongo driver methods in the format db.collectionName.update (saving the collection handles onto a db object as a form of pseudo-namespacing), which makes it a lot easier to tell the difference between db.collectionName.update vs someOtherObject.update. But I recognize that this is an assumption we’re making based on how we define our collections, so it might not work in other codebases.

You’re right, in our codebase, we don’t use db.collectionName. syntax, we always use exported collection variables. In my script, I can open the exported file, look for the variable, if it came from new MongoCollection() init then it is a mongo collection.
But it won’t work if you do something weird likes changing the variable name before export, etc.

Would it be possible to use top-level await so as to avoid making the function which contains the await expression become an async function?

I don’t get it. Can you give an example?

I haven’t tried it yet – and I may not know how it works it.

My understanding is that node.js v14 supports top-level await, which I think is the ability to use await outside of an async function.

Here’s a reference. I’m probably missing key requirements.

I don’t think you can move everything out of function. How can you pass it the variable?

meteor wraps all packages (and the app code) in a function, so the ability to use top level await meaningfully depends on meteor, not node

1 Like

So top-level await cannot run in a non-async function? I thought that was the whole point of it. I had a feeling there was something I was missing about it.

top level await in node can run outside of a function, but top level await in meteor cannot without changes to meteor - because ultimately this code:

await whatever();

gets converted to something like

(function() {
   await whatever();
})()

I believe Meteor needs to change that wrapper to be async function then change it’s boot-loader to Promise.await it. Things get a bit muddier since meteor also converts await to Promise.await

1 Like

Top level await is coming in Meteor 3. It currently is in development at Top Level Await by zodern · Pull Request #12310 · meteor/meteor · GitHub.

I believe Meteor needs to change that wrapper to be async function then change it’s boot-loader to Promise.await it. Things get a bit muddier since meteor also converts await to Promise.await

We were initially planning to release it in a Meteor 2.x version, but supporting top level fiber code in a backwards compatible way, and trying to create a spec compliant implementation of top level await that uses Promise.await seemed to be incompatible, so we are releasing it in Meteor 3 which uses native async/await instead of Promise.await. With enough time and effort I think we could have gotten it to work, but it doesn’t seem worth it with the latest plan for removing fibers.

Top level await only enables using await outside of any function. If you use await inside a function, the requirement for the function to be async still exists.

5 Likes

@zodern, once TLA is available in Meteor, does it mean Meteor will also support ES Modules? Or was this just syntactic sugar to mimic TLA?

It isn’t native top level await. Like ES Modules, it is implemented in reify. The PR for that part is at Top level await by zodern · Pull Request #4 · meteor/reify · GitHub. It tries to be spec compliant. When testing how compliant it is for the timing and order it runs modules, it is equivalent to webpack and v8, and significantly better than the other bundlers I’ve tested.

Meteor will still need to support environments for a while where using native module isn’t possible or has downsides compared to using reify. Next year I want to see if there is someplace we could start using them - maybe the meteor tool, or build plugins, or at least parts of the server.

3 Likes

For anyone interested: I’ve set up a small repo with the necessary files to have ESlint help you with tracking down code that should be updated.

You can find it here: GitHub - cluelesscamel/meteor-fiber-free-diet-eslint: Custom ESLint rules to help track down non-Async meteor code

7 Likes

It looks like it will work with both back-end and front-end codes.

1 Like

Yes, it really just flags any something.update/insert/remove... which is what we wanted.

1 Like

I just pushed some updates to make it works with typescript return type.

it now supports Meteor 2.9

I’m waiting for Meteor 2.10 migration document to update the tool.

2 Likes

Hi @minhna just want to check if you have made updates for Meteor 2.10 and beyond. Now with 3.0-alpha.11 coming out this will get renewed attention.

Also I’m thinking if it would be possible to include migration for common packages like the roles package which will soon include Async calls?

1 Like

By checking changelog, I don’t see the new core async function since 2.10 but I’m not sure about the core packages.
Your idea about including migration for common packages is very good. I’m thinking about that.

1 Like

I just interlink the 2 posts as they seem to be related Meteor 3.0 - async functions eslint plugin - #2 by copleykj