emberjs / ember.js

Ember.js - A JavaScript framework for creating ambitious web applications
https://emberjs.com
MIT License
22.46k stars 4.21k forks source link

[Bug] createCache + HelperManager args are recycled upon update, meaning there is no way to access previous args? #19758

Open NullVoxPopuli opened 2 years ago

NullVoxPopuli commented 2 years ago

🐞 Describe the Bug

I have a resource implementation that passes the previous instance of a resource to the next instance of a resource, but the args are the same in both resources. My hunch is that there is either a bug in the HelperManager I've made, or I don't understand something about the HelperManager (maybe likely?).

🔬 Minimal Reproduction

  1. clone this branch: https://github.com/NullVoxPopuli/ember-resources/pull/196/files#diff-2dc1fb4dff6d6d3ac74f7f727755ef3bd0dcb32373b3d40c6c896a3a577e4802R57
  2. start the tests
  3. open the console
  4. visit: http://localhost:4200/tests?hidepassed&testId=888d27c7

Observe that: image

😕 Actual Behavior

createCache's previous instance's args have the same values as the current instance's args.

The only work around I can think of is to consume all args eagerly in createCache and set args to a vanilla object, rather than the tracked proxy / thunk that args currently are.

🤔 Expected Behavior

The previous instance's args are unchanged

🌍 Environment

➕ Additional Context

lifeart commented 2 years ago

args is stable proxy for component instance, as I remember, kinda related: https://github.com/emberjs/ember.js/issues/19130, internals: https://github.com/glimmerjs/glimmer-vm/blob/master/packages/@glimmer/manager/lib/util/args-proxy.ts

NullVoxPopuli commented 2 years ago

Is that same code used for the HelperManager? components aren't involved here.

But also, does that mean, no matter how many times I update args, all args are the same reference? If that's intended that's fine -- I can work around that :D

lifeart commented 2 years ago

@NullVoxPopuli you could check how "captureRenderTree" function is working, because args is objects in result (not proxies)

NullVoxPopuli commented 2 years ago

how do I do that? I've never used captureRenderTree -- also, how does that work if my reproduction tests don't use the DOM?