now() returns not a relevant time when no active subscriptions
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- typescript
- Domain
- frontend
Research direction
Start in src/now.ts at the _isComputingDerivation check around lines 35-38, then run the TypeScript reproduction from the issue and observe behavior before and after disposer() removes the reaction. The fix is done when imperativeCheck continues reporting decreasing remaining times after the reaction is removed and stops when the counter reaches zero.
Written by the indexing model from the issue text.
Description
There is a fix in #40, but it seems broken now, code:
export function now(interval: number | "frame" = 1000) {
if (!_isComputingDerivation()) {
// See #40
return Date.now()
}
...
In case no subscriptions, _isComputingDerivation always return false. I am not sure why, even if wrap now() in action.
Reproduction:
import {makeAutoObservable, reaction} from "mobx";
import {now} from "mobx-utils";
class Counter {
stopTime: number = 0;
get remaining() {
const delta = this.stopTime - now(1000);
return delta > 0 ? delta : 0;
}
get done() {
return this.remaining <= 0;
}
constructor() {
makeAutoObservable(this);
}
start(duration: number) {
this.stopTime = Date.now() + duration;
}
imperativeCheck() {
console.log(`imperativeCheck: remaining=${this.remaining} done=${this.done}`);
}
}
const counter = new Counter();
const disposer = reaction(
() => counter.remaining,
(remaining) => {
console.log(`reactiveCheck: remaining=${remaining}`);
},
);
console.log("start timer for 10s");
counter.start(10 * 1000);
let imperativeCheckCounts = 0;
scheduleImperativeCheck();
function scheduleImperativeCheck() {
imperativeCheckCounts++;
setTimeout(() => {
counter.imperativeCheck();
if (imperativeCheckCounts === 2) {
console.log("Now we remove reaction");
disposer();
}
if (!counter.done) scheduleImperativeCheck();
}, 2000);
}
Result:
start timer for 10s
reactiveCheck: remaining=10000
reactiveCheck: remaining=8998
imperativeCheck: remaining=8998 done=false
reactiveCheck: remaining=7994
reactiveCheck: remaining=6993
imperativeCheck: remaining=6993 done=false
Now we remove reaction
Called `get` of a subscribingObservable outside a reaction. Current value will be returned but no new subscription has started
Called `get` of a subscribingObservable outside a reaction. Current value will be returned but no new subscription has started
imperativeCheck: remaining=6993 done=false
Called `get` of a subscribingObservable outside a reaction. Current value will be returned but no new subscription has started
Called `get` of a subscribingObservable outside a reaction. Current value will be returned but no new subscription has started
imperativeCheck: remaining=6993 done=false
Called `get` of a subscribingObservable outside a reaction. Current value will be returned but no new subscription has started
Called `get` of a subscribingObservable outside a reaction. Current value will be returned but no new subscription has started
imperativeCheck: remaining=6993 done=false
Called `get` of a subscribingObservable outside a reaction. Current value will be returned but no new subscription has started
Called `get` of a subscribingObservable outside a reaction. Current value will be returned but no new subscription has started
imperativeCheck: remaining=6993 done=false
Called `get` of a subscribingObservable outside a reaction. Current value will be returned but no new subscription has started
Expected behaviour: After removing reaction, imperativeCheck should log decreasing times and stop...
Note: this is a somewhat artifical example. In the actual application we have some logic based on the current time, which is used in many places, some of which are in the reactive context, whereas others are not. In theory, we might write this logic twice: one with now() from mobx-utils, and the other with Date.now(). However, it is a huge duplication of code and makes the code unreadable.
- Dominant language
- TypeScript
- Stars
- 1.2k
- Forks
- 130
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from mobxjs/mobx-utils
-
Difficulty 3/5 1-2 days Newbie friendliness 38/100
mobxjs/mobx-utils#338 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 45/100
mobxjs/mobx-utils#329 · 1 reaction ·
-
Difficulty 3/5 1-2 days Newbie friendliness 52/100
mobxjs/mobx-utils#327 ·
-
Difficulty 3/5 1-2 days Newbie friendliness 35/100
mobxjs/mobx-utils#324 · 2 reactions ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 45/100
mobxjs/mobx-utils#321 ·
All issues in mobxjs/mobx-utils
Similar issues
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P3
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 76/100
-
code-quality refactoring
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
github/gh-aw-firewall#8816 ·
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
langchain-ai/deepagents#6450 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
vercel/react-tweet#225 ·