Open dvdkhlng opened 4 years ago
Note that I never managed to fully fix Mithril's stream implementation WRT the above bugs, when considering all the interactions between streams returning SKIP and pending streams.
I think the crucial issue I failed to fix was that SKIP would create an inconsistent state: some nodes would be marked as "changing" fist, but due to SKIP would never get the final value ("finalChange").
If finally gave up and wrote a new stream implementation from scratch that represents stream dependencies as a graph and propagates changes breadth-first. My implementation is not exactly API compatible with Mithril streams, and I may not be able to share it here. It would also likely break existing code, as it is difficult to exactly reproduce the current implementation's semantics.
Mithril version: "next" branch (rev dca44b14aba9994c236af3dcc5b7845c31cf80b1) Browser and OS: Ubuntu / Firefox 80
The following unit-test code (using tinytest) illustrates the issue:
The last two eq() assertions WRT numUpdates are violated (numUpdates will be reported as 2). This directly contradicts the manual which states that "Computed properties in Mithril are updated atomically: streams that depend on multiple streams will never be called more than once per value update[..]"
This issue can be fixed by making sure that combine() only pushes the change downstreams, after all of the mappers received the update that was advertised by the preceding invokation of _changing().
The following patch solves the issue for me (but may not be good enough for the mithril codebase, my js coding skills are limited).
This is only one half of the problem. Stream.combine() does not propagate the _changing() signal down-streams. This leads to more atomic semantics mis-behaviour when chaining Stream.combine(). See this unit test that still fails in spite of the fix above:
I can mitigate this problem by making stream.combine() forward the _changing() notification as follows:
Update: modified the first patch as it failed to pass the trivial test