universal-ember / reactiveweb

Reactive primitives for the web
https://reactive.nullvoxpopuli.com
MIT License
11 stars 5 forks source link

ember 5.6+ causes tracking issues #110

Open Techn1x opened 2 months ago

Techn1x commented 2 months ago

Hello!

I recently started hitting some strange tracking issues with a combination of trackedFunctions and getters. The behaviour I noticed was;

This gives an idea of what I have. The example is contrived but it represents how my code is structured

abc = trackedFunction(this, async () => {
  const items = await getItems()
  return items
})

// this correctly returns "undefined" while abc is pending, but never runs again when abc is done
get firstItem() {
  return this.abc.value?.[0]
}

// this receives the firstItem "undefined" but never updates
def = trackedFunction(this, async () => {
  if (!this.firstItem) return []
  const manifestBundle = await fetchForItem(this.firstItem)
  return manifestBundle
})

get currentManifestBundle() {
  return this.def.value ?? []
}
{{#each this.currentManifestBundle as |manifest|}}
  ...
{{/each}}

From what I can tell, it is to do with ember-source - 5.4.1 works, 5.6 does not (nor does 5.8). I've put together this failing PR that might help https://github.com/universal-ember/reactiveweb/pull/109

Techn1x commented 2 months ago

Oh I see the tests are passing on ember 5.8 now! nice. I will consume next update when published and see if my issue is resolved, otherwise I'll write up a failing test that targets the behaviour I am seeing. Thanks!

NullVoxPopuli commented 2 months ago

Gonna re-open this as I didn't actually debug it, and the 5.6 to 5.8 changes shouldn't be affectiing reactiveweb -- however -- the VM did get upgraded in 5.6, and reactivity did get more strict about what you're allowed to do.

// this correctly returns "undefined" while abc is pending, but never runs again when abc is done

what updates abc?

Techn1x commented 2 months ago

These are all wrapped in a class, I set something in a constructor. Wonder if that's got something to do with it?

class LessonActivity {
  lesson: number

  constructor(lesson: number) {
    // setOwner(...) etc
    this.lesson = lesson
  }

  abc = trackedFunction(this, async () => {
    const items = await getItems(this.lesson)
  ...
}

and the template would look something like this

openLesson = () => {
  this.lessonActivity = new LessonActivity(1)
}

<template>
  ...
  {{each this.lessonActivity.currentManifestBundle as ||}}
    ...
</template>
NullVoxPopuli commented 2 months ago

Is lesson activity tracked?

Techn1x commented 2 months ago

Yeah it is. I can try to create a failing test if nothing obvious is coming to mind

NullVoxPopuli commented 2 months ago

Yeah, nothing obvious is jumping out at me.

A failing test pr would be wonderful!

Techn1x commented 1 month ago

Put together this test case which closely matches what I am aiming to do, though it is succeeding 😅 https://github.com/universal-ember/reactiveweb/pull/115

Back to the drawing board. I'm going to try copying that test case over into my application and see if it fails/succeeds there under ember 5.8

NullVoxPopuli commented 1 month ago

thanks for your efforts!!!

Techn1x commented 1 month ago

Managed to get the test to fail! Commented on that failing test PR, it's something to do with modifiers consuming the tracked-function before other things.

NullVoxPopuli commented 3 weeks ago

I think also, @wycats identified a bug in ember-source 5.6+, so that's probably what you're running in to here -- my hope is that once the fix lands (and is backported) your failing test will no longer be failing