DrSensor / nusa

incremental runtime that bring both simplicity and power into webdev (buildless, cross-language, data-driven)
MIT License
4 stars 0 forks source link

`abstract class Scope` #27

Closed DrSensor closed 1 year ago

DrSensor commented 1 year ago
import * as ptr from "vheap.ts"

/** @ts-rule noImplicitOverride */
abstract class Scope {
  $host = ptr.hostElement

  protected abstract on$load(state?: "init" | "revisit")

  protected abstract on$bind(state?: "unbind" | "rebind")
  unbind() {...}
  bind() {...}
  rebind() {
    ...
    this.unbind()
    this.bind()
  }

  protected abstract on$transition(next: Document | Element)

  protected abstract on$remove()
  remove() {...}
}

export default function(Base: Class) {
  ...
} as typeof Scope | (Base: Class) => typeof Scope

Note the lifecycle hook is protected which mean user should not override it outside the class declaration

The dollar sign is reserved for:

  • excluding it from binding
  • use for detecting if props/methods is runtime specific hook
  • to be override by 3rd-party library at runtime (i.e this.on$remove = customRemovalFn)

Usage

export default class extends Scope {}

or when used in mixin

export default BaseClass => class extends Scope(BaseClass) {}

💡 Tip: Check if new.target is defined. When false, return BaseClass => abstract class extends BaseClass

DrSensor commented 1 year ago

I'm really not sure about this. Both conditional and list rendering rely on slot so it actually doesn't attach or remove dom node from document. Even <render-scope>.disconnectedCallback() only being called if author use ref. No framework abstraction over it.