proposal-decorators icon indicating copy to clipboard operation
proposal-decorators copied to clipboard

I wish "context initializers" ran in definition order.

Open trusktr opened this issue 3 months ago • 28 comments

I wish the following, implemented with context.addInitializer() only, would simply work:

class MyClass {
  @signal a = 1
  @signal b = 2

  @memo get sum() {
    return this.a + this.b
  }
}

It doesn't work because the context initializer ordering is like the following:

class MyClass {
  get sum() {
    return this.a + this.b
  }

  constructor() {
    // initializer for sum
    this.a = 1
    // initializer for a
    this.b = 2
    // initializer for b
  }
}

Trying to set up reactivity this way for the getter will result in a and b being undefined, leading to a NaN.

function signal(_, context) {
  context.addInitializer(function () {
    // patch this[context.name] with signal descriptor
  })
}

function memo(_, context) {
  context.addInitializer(function () {
    // patch this[context.name] (or proto[context.name] once) with
    // memo descriptor, and run it immediately to track dependencies
  })
}

The @memo initializer will run first before either @signal initializer.

I tend to expect them to run in order. Context initializers run per instance, so I don't see a good reason for them not to be in order.

trusktr avatar Nov 22 '25 07:11 trusktr