type ProfileSpec = Frond.NodeSpec<{
  readonly args: Frond.Args.None;
  readonly key: Frond.Key.Singleton;
  readonly deps: {
    readonly http: Frond.Dep<typeof HttpTransportNode>;
  };
  readonly result: Profile;
}>;

export class ProfileNode extends Frond.NodeBase<ProfileSpec> {
  static readonly spec = Frond.resourceSpec<ProfileSpec>({
    tag: Frond.tag("app/profile"),
    key: () => Frond.Key.singleton(),
    dependencies: Frond.dependencies(() => ({
      http: Frond.dep(HttpTransportNode, Frond.Args.none),
    })),
    driver: Frond.Driver.Async<ProfileSpec>({
      // Cannot load before http is ready.
      // Eviction on sign-out runs through the same disposers.
      acquire: Frond.Driver.Acquire(({ deps, signal }) =>
        deps.http.result.getProfile(signal)
      ),
    }),
  });

  // Derived view fields stay close to the data, not the screen.
  get displayName(): string {
    return this.result.displayName;
  }

  get initials(): string {
    return initialsFromName(this.result.displayName);
  }
}