eleventy icon indicating copy to clipboard operation
eleventy copied to clipboard

add: make log filter async friendly by adding logAsync

Open Snapstromegon opened this issue 1 year ago • 8 comments

Right now the log filter logs the passed in values directly. This isn't always helpful when working with async values e.g. in webc components. This change adds the logAsync filter to also take promises as any value and awaits them, so you always get some useful output.

It could be possible to just eagerly return the value in the sync filter and then use a .then call to log the values, but that would leave room for unexpected data mutation, so I didn't implement it that way for now.

resolves #3133

Snapstromegon avatar Dec 31 '23 10:12 Snapstromegon

Can we test for promises in log and await instead? It might be preferable to make log async friendly in 3.0

zachleat avatar Jan 02 '24 15:01 zachleat

If we make the log filter itself async, it would no longer be available in languages that don't support async filters (like handlebars).

I've just seen that addFilter only adds the filters to Liquid, JavaScriptFunctions and Nunjucks filters, so we could make it indeed async for everything.

Snapstromegon avatar Jan 02 '24 16:01 Snapstromegon

Ah, sorry—I meant (kind of) like this

config.addFilter("log", (...messages) => {
  // if any of messages are a promise, do promise things
  if(messages.find(entry => /* promise test */)) {
    // out of order, but that’s preferable to errors in non-async
    Promise.all(messages).then(msgs => console.log(...msgs));
  } else {
    console.log(...messages);
  }
});

some prior art (not exactly): https://github.com/11ty/eleventy/blob/d77d7fad6dfcbb872f0487345c2189981c509bcc/src/UserConfig.js#L272

zachleat avatar Apr 09 '24 13:04 zachleat

Ahh okay, I see what you mean and I will adapt it.

Snapstromegon avatar Apr 09 '24 13:04 Snapstromegon

Thinking about it, we could even return a promise if any of the inputs is async. That would also fix the ordering issue for async cases or am I missing something here?

Snapstromegon avatar Apr 09 '24 14:04 Snapstromegon

@zachleat are we intending to support only native Promises here, or also all "thenables" (so e.g. Bluebird promises and similar custom promise implementations)? I think they would be detectable by testing if something has a .then() method, but that seems flaky too.

Snapstromegon avatar Apr 09 '24 14:04 Snapstromegon

native promises only is fine. And I like the promise return! That wouldn’t work with our async filtering stuff though, since it checks if the callback is async (not the return value).

zachleat avatar Apr 09 '24 16:04 zachleat

@zachleat Good catch.

Since the removal of some of the built-in templating languages, is there a reason to not just add it via addAsyncFilter?

Snapstromegon avatar Apr 09 '24 17:04 Snapstromegon