question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

forwardRef operator or it's analog proposal

See original GitHub issue

Because of architecture of an Effector where all units and operations are written in top level of ES modules, and they start initialization in a moment when ES modules are imported you may often fall into trouble with circular dependencies and therefore broken build with “ReferenceError: Cannot access “$myStore” before initializaion” or even worst cases which sometimes very hard to debug and fix.

Proposal

The proposal is introducing a forwardRef concept:

sample({
 source: forwardRef(() => $myStore), // or simply define fn instead of references to other stores
 target: '...'
})

The forward ref fn is called somewhere on later phase when all ES modules tree is already initialized (batch and flush on next micro task, or synchronously execute when very first event is dispatched).

I saw many suggestions and solutions how to structure the code to avoid this kind of error, many of them far from ideal and require an additional boilerplate. Sometimes even when everything structured in a right way you still have circular deps problem because of complicated structure of components and stores, wich really hard to follow and find where exactly problem come.

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:26 (14 by maintainers)

github_iconTop GitHub Comments

2reactions
zerobiascommented, May 5, 2022

Okay, then now we need to do a smoke test: is it enough to move to defer only links with target?

Let’s assume naive defer implementation (it will not be async in prod btw):

export function defer(fn) {
  return Promise.resolve().then(fn)
}

Please try to use it in your projects. Is it useful, did you avoided circular loops? Have you been able to use it in all the places where you would like to? Note that methods that create new units will have to be rewritten to an explicit unit creation and method with target

1reaction
zerobiascommented, May 4, 2022

What about is.store which should return immediately?

If you want to create new unit you will not be able to use neither promises nor domain.defer anyway

So your code will looks like that

import {delay} from 'patronum'
import {domain} from './root'
import {triggerA, triggerB, requestFx} from './plain'
import {$fxDelay, delayedTriggerB} from './cyclic'

// this unit have everything to be created at the root
export const delayedTriggerA = delay({
  source: triggerA,
  timeout: 50
})

// this unit need cyclic $fxDelay
export const delayedRequest = createEvent()

domain.defer(() => {

  // link for unit in that module
  delay({
    source: delayedRequest,
    timeout: $fxDelay,
    target: requestFx,
  })

  // link for unit in other module
  delay({
    source: delayedTriggerB,
    timeout: 50,
    target: triggerB,
  })

})
Read more comments on GitHub >

github_iconTop Results From Across the Web

Forwarding Refs - React
Ref forwarding is an opt-in feature that lets some components take a ref they receive, and pass it further down (in other words,...
Read more >
Nest can't resolve dependencies of the UsersService ...
I'm going to make some assumptions about your service constructors, as you haven't provided those: You have what looks to be a circular ......
Read more >
NJ\S/\ - NASA Technical Reports Server
appear to offer promise for a significant improvement in aviation safety. ... full range of simulation variables without special operator actions such.
Read more >
How to use React's forwardRef function - Felix Gerschau
Our task is to forward the ref that the Input component receives to the HTML input element. We do that by wrapping the...
Read more >
Joint generation dispatching of power system with nuclear power ...
A joint nuclear-thermal-wind-heat storage generation dispatching model is ... Some countries have proposed that NPPs can participate in the daily peak load ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found