Giter Club home page Giter Club logo

Comments (17)

etienne-dldc avatar etienne-dldc commented on August 14, 2024 5

Hi,
I can't speak for @christianalfoni but IE11 has been discussed in the past and the conclusion was that, yes it's probably possible to get Overmind to work without Proxies but that would imply developing and maintaining a whole new system of state read/write tracking which would significantly slow down development, make future improvement way harder and increase the bundle size.
Because of these reasons, there are no plan (as far as I know) to get IE11 supported.
If you haven't yet you can take a look a CerebralJS which support IE and is similar to Overmind in its approach.

from overmind.

FWeinb avatar FWeinb commented on August 14, 2024 2

@chimon2000 it is not just a question of including immer in overmind but a functional one. I worked on proxy-state-tree, the underlying library that is doing the mutation/access tracking for overmind. Immer and proxy-state-tree are fundamentally different in there implementation and scope of work.

I don’t see a way how overmind could use the approach of immer to keep track of state changes and dependency access without compromising its functionality.

We talked a whole lot about the bold move of dropping IE11 support in overmind and decided that it would be time to free us of the burden to support an old browser.

There is always the possibility of having a Babel/typescript plug-in to get IE11 support but that would be a big investment into a technology that will be gone in a few years (as edge will be based on chromium and come to win 7)

As said before getting IE11 support would be a huge investment in development resource that could be better used to improve to overall development experience by focusing on documentation and the devtools.

from overmind.

luisherranz avatar luisherranz commented on August 14, 2024 2

I've been exploring this topic some more lately. The problem lays with the async functions and sync mutations. I'm going to assume Overmind doesn't need sync mutations and it's ok if they happen before the next flush (correct me if I'm wrong).

With a sync action, you can wait until the action returns, then do a deep-diff of state:

const myAction = ({ state }) => {
  state.model.year = 2016;
  // when this action returns, do a deep-diff in ie11.
}

With async actions it's not so simple:

const myAction = async ({ state }) => {
  state.model.year = 2016;
  // 1. You need to do a deep-diff here
  await something();
  state.model.year = 2017;
  // 2. You need to do a deep-diff here
  await somethingMore();
  state.model.year = 2018;
  // 3. You need to do a deep-diff here
}

For the first deep-diff (1), Overmind could check if the function returns a promise and if it does, wait with setTimeout until it yields or returns and do the first deep-diff.

The second deep-diff (2) is the problematic one because Overmind doesn't know the function has resumed. With es6 proxies, Overmind can know because a mutation coming from that action has occurred, but in es5 state.model.year = 2017 is completely transparent.

The third deep-diff (3) is easy again because the promise is resolved.

Some ideas to solve it:

  • Using generators instead of async functions but for some reason (that I don't quite understand yet) they're kind of ugly and nobody wants to use them πŸ˜†
  • Forcing people to always use effects for their awaits. That way Overmind can know when the action yields (calls an effects) or resumes (the effect resolves) and can do deep-diff in the correct places. Not pretty either, as it deviates from normal JavaScript:
const myAction = async ({ state, effects }) => {
  state.model.year = 2016;
  await effects.something(); // <- this is ok
  state.model.year = 2017;
  await fetchSomething(); // <- this is forbidden
  state.model.year = 2018;
}
  • Insert deep-diff's with babel in async actions. This won't be very performant of course. I don't know "how intelligent" can a babel plugin be.
const myAction = async ({ state, effects }) => {
  state.model.year = 2016;
  checkForMutations(state); // <- inserted by babel
  await effects.something();
  checkForMutations(state); // <- inserted by babel, but unnecessary, wasted CPU
  state.model.year = 2017;
  checkForMutations(state); // <- inserted by babel
  await fetchSomething();
  checkForMutations(state); // <- inserted by babel, but unnecessary, wasted CPU
  state.model.year = 2018;
  checkForMutations(state); // <- inserted by babel
}

from overmind.

luisherranz avatar luisherranz commented on August 14, 2024 1

Yes, the babel plugin is sure a tricky one. I'm on brainstorm mode here :)

Anyway, I've been taking a look at immer (mutation side) and memoize-state (tracking side) and even tho they rely on es6 proxies they have managed to work with es5 as well.

I'll try to dig more into their code and if I find something useful I'll let you know here.

from overmind.

christianalfoni avatar christianalfoni commented on August 14, 2024 1

https://www.pcworld.com/article/3393198/microsoft-edge-ie-mode.html

from overmind.

vinceprofeta avatar vinceprofeta commented on August 14, 2024

@christianalfoni is this something that could make it in the pipeline and if so what would a time frame look like? Overmind has been my favorite approach yet, but unfortunately this is a deal breaker.

from overmind.

chimon2000 avatar chimon2000 commented on August 14, 2024

I am more advocating for producing a separate bundle for ES5 than increasing the size of the current bundle. Both are viable options, but I acknowledge that it would be more work for maintainers. What is the current size restriction / goal for Overmind? How much would a non-proxied version increase the size of Overmind? I imagine the worst case (just reusing immer internally) would be around 4kb (min+gz).

I understand that CerebralJS is similar, but there are differences. Also, is the plan to always have feature parity between Cerebral and Overmind? If so, I'd think that would be more difficult than producing a backwards compatible version of Overmind. If not and Overmind is the way forward, then it would be pretty difficult to recommend Cerebral.

from overmind.

chimon2000 avatar chimon2000 commented on August 14, 2024

Fair enough

from overmind.

luisherranz avatar luisherranz commented on August 14, 2024

I wonder if the Chrome polyfill could work with Overmind:
https://github.com/GoogleChrome/proxy-polyfill

from overmind.

eirikhm avatar eirikhm commented on August 14, 2024

@luisherranz Sadly no. The polyfill supports just a limited number of proxy 'traps'. It also works by calling seal on the object passed to Proxy. This means that the properties you want to proxy must be known at creation time.

from overmind.

luisherranz avatar luisherranz commented on August 14, 2024

I think the question is if Overmind can be designed to replace entire objects, which is the requirement of the polyfill:

The following line will fail (with a TypeError in strict mode) with the polyfill, as it's unable to intercept new properties-

p.model.year = 2016;  // error in polyfill

However, you can replace the entire object at once - once you access it again, your code will see the proxied version.

p.model = {name: 'Falcon', year: 2016};
// model Object {name: "Falcon", year: 2016}

For example, in "es5-mode" mutations could be triggered by a deep comparison of the previous state vs the new one, then replacing entire objects when needed.

The deep comparison would be something like this:
https://github.com/theKashey/immutable-changes/blob/master/src/index.js

Once that's done the tracking should work just fine.


By the way, I'm not stating that overmind should have support for IE11, I'm just wondering if it would be possible to do, while keeping the same external API.

from overmind.

luisherranz avatar luisherranz commented on August 14, 2024

For example, one problem of the approach I just mentioned would be the mutations made in async functions after the first await. I wonder if there's a way to trigger the deep comparison asynchronously...

from overmind.

luisherranz avatar luisherranz commented on August 14, 2024

The only way that comes to my mind right now is to trigger the comparison at regular intervals. Not ideal but hey, man, update your browser πŸ˜†

Another way to solve this issue could be a babel-plugin to substitute those mutations:

state.model.year = 2016;
// transpiled to =>
set(state.model, 'year', 2016);

from overmind.

FWeinb avatar FWeinb commented on August 14, 2024

@luisherranz that would be the basic idea of a babel-plugin. But it is not that simple. The tricky part is to identify and track state variable access/mutation by doing static code analysis of javascript/typescript. There are a million edge cases that need to be thought of for having this work reliable.

You could e.g. pass your state object into an arbitrary function inside an action and have it manipulate the state. In typescript the actions functions are at least typed but doing this in plain javascript would be nearly impossible.

from overmind.

christianalfoni avatar christianalfoni commented on August 14, 2024

Yeah, I believe they work with quite a bit of limitations. But please, if there is an elegant we should look into it :)

from overmind.

christianalfoni avatar christianalfoni commented on August 14, 2024

Very interesting suggestion!

Related to async it can actually work if it detects a promise being returned. It does a setTimeout and does a new diff until the promise resolves. Though this has a problem with:

export const someAction = ({ state }) => {
  setTimeout(() => {
    state.foo = 'bar'
  })
}

Cause there is no way to know when the action is done. And there is no way to warn about this. That said, it is an edge case and since it is async it will be part of the next flush anyways.

My biggest worry here is performance. The deep-diff would require trigger the garbage collector a lot and also performance is issue. Cause after every flush you have to create a copy of the state, which requires you to go through everything. And on the next flush you have to go through it again.

Microsoft is just about to release their new browser which can run in IE11 mode. Meaning that companies has absolutely no reason to not change the browser. They can run IE11 mode on old internal apps/pages and for everything else they get a modern browser.

"
Internet Explorer mode. Instead of forcing business users to switch between two different web browsers so that they can access internal websites that still required IE, Microsoft Edge will feature a fully-compatible Internet Explorer mode via a new tab. That way, users can run legacy sites and modern sites side-by-side in one browser.
"

I really like the thought experiment, though I truly think it will be work wasted. Microsoft should fix this... any they are with the new Edge browser :-D

from overmind.

luisherranz avatar luisherranz commented on August 14, 2024

My biggest worry here is performance. The deep-diff would require trigger the garbage collector a lot and also performance is issue.

Yes, performance would be definitely worse than in the proxy version.

Microsoft is just about to release their new browser which can run in IE11 mode.

Amazing news, I didn't know about that :)

from overmind.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.