live-server icon indicating copy to clipboard operation
live-server copied to clipboard

Feature: Control over reloads via API

Open chbndrhnns opened this issue 2 years ago • 9 comments

Thank you for making this library!

Using the API, I'd like control over reloads. Suggestion: a flag that determines if automatic reloads should occur and a function to call in order to trigger a reload.

chbndrhnns avatar Mar 16 '23 14:03 chbndrhnns

Yes, me too. And that's not a coincidence, since we're working on the same project together.

mightyiam avatar Mar 16 '23 14:03 mightyiam

Do you mean like this?

let config = Config {
    reload: true
};
listen("127.0.0.1", 8080, "./", config).await.unwrap();

Or would you like to provide an example?

lomirus avatar Mar 17 '23 02:03 lomirus

That brings us half way there. Additionally, we'd like to be able to trigger individual reloads ourselves. I know I'm not providing you with an API design at this point. It's not immediately apparent to me what that design would be.

mightyiam avatar Mar 17 '23 02:03 mightyiam

What's the purpose for you to determine every reloads? For example, do you want to detect if some files change and then trigger reloads or want to control the reloads frequency manually?

lomirus avatar Mar 17 '23 03:03 lomirus

A page may consist of multiple files. And in our case it does. If these files get updated too far apart from each other, then the developer experiences multiple reloads. This is what we're trying to prevent. If we control the triggering of reloads, we can make sure that the developer experiences one reload per change they made.

mightyiam avatar Mar 17 '23 03:03 mightyiam

They hit save once and experience one reload. Well, at least that's the ideal. Currently, they experience two reloads for each time they save a source file. That is because we have a program that is watching the output HTML files and spitting out a CSS file whenever they change (tailwindcss). So each change to an HTML file is followed by a change to a CSS file.

mightyiam avatar Mar 17 '23 03:03 mightyiam

I think these problems are worth considering but should be done by the library instead of the users in order to avoid the extra repetitive work.

Here are my solutions:


1. Irrelevant Reload

Use html-editor (also my library) to analyze the src/href attributes in the HTML file of the to find which assets it depends. And then refresh only when the files it depends or itself are modified.

The problem is that it will increase the response time since the parse process need extra time. I may need to improve the html-editor performance (it's still far from what I expected) first before implementing it into this repository.

2. Extra Repetitive Reload

Set a minimum interval like 500ms. If in this interval any file is changed, it will be pushed to the queue, and then when the timer is over, the server will check the queue to trigger at most 1 reload for each file.


If you agree the solutions, I will split this issue into 2 new issues and then work on it. Or if not, feel free to give me any suggestion.

lomirus avatar Mar 17 '23 04:03 lomirus

The source of truth regarding updates to the website is somewhere in the program that updates them.

When the boundary is an inconvenient one, such as a command, one is inclined to reduce interaction across that boundary and to develop such features that ignore the source of truth and try to figure out when there was an update by looking at the files and updates to individual files. This is detective work as if the source of truth is not available.

When the boundary is an API, then the truth can be propagated from the source of it conveniently to the mechanism that can tell the browser to reload.

I should be able to tell live-server via the API "there was an update to the website", which is different then individual file updates.

mightyiam avatar Mar 17 '23 09:03 mightyiam

Ok, it makes sense. Maybe these two solutions above can be added as another update in the future.

Now for this issue, here's another possible API:

listen_manually("127.0.0.1", 8080, "./", |file: Path, behavior: Behavior| {
  if is_relevant_file(file) {
    match behavior {
      Behavior::Modify => true,
      _ => false
    }
  } else {
    false
  }
}).await.unwrap();

This closure can be expanded like returning aVec<Url> to only reload part of the pages or adding other parameters, but it will also need extra efforts to implement.

lomirus avatar Mar 18 '23 08:03 lomirus