Development notes

Signal inputs, outputs, and queries

Most component bindings now use input(), output(), and viewChild(). 703 files. Routing, SCSS, and business logic are unchanged. SharedModule and control-flow templates are a different PR.

commit 150713b319 hotfix/release-0.0.23/signal-inputs PR 10872

What changed

Angular's official combined schematic, one pass over src with a 10 GB heap. It finished in about two minutes.

NODE_OPTIONS=--max_old_space_size=10048 npx ng generate @angular/core:signals --path=src --analysis-dir=src --defaults --interactive=false
APISchematicIn the tree now
input()1108 / 13991089 input() fields. 313 @Input left.
output()383 / 389379 output() fields. 10 @Output left.
viewChild() / viewChildren()562 / 603409 + 15 signal queries. 46 @ViewChild and 2 @ViewChildren left.

I did not turn on bestEffortMode. The leftovers are ones the schematic refused because converting them would break the build or the runtime.

Fixes after the schematic

The first QA build had about 500 errors. Most of that was the schematic being sloppy with types and with this., not a surprise on a repo this size. The ones that actually mattered:

What brokeWhat I did
viewChild('foo') with no type Hundreds of originals had no annotation, so the signal came back as unknown and openModal() failed. Restored types from git, or any when there was nothing to restore.
ngx-bootstrap initialState on AlertModal Object.assign would have overwritten the signal functions with strings. I put those inputs and the EventEmitter outputs back. This modal is opened that way from a lot of places.
Portfolio song / podcast / video parents this.step3Component.postPriceComponent.ppForm became a mess of locals pointing at the wrong object. Wired them back through step3Component()?.postPriceComponent().
private readonly screenClick = output() Angular rejects a private output. Dropped private on video-player-v2. That one took the whole player out of every standalone import list until it compiled.
header-layout brandClick.observed output() has no .observed. Kept the EventEmitter so a logo click still goes home when the parent is not listening.

What stayed on decorators

  • @Input() set … setters, and fields written from TypeScript or ngOnChanges.
  • Required inputs the schematic could not type.
  • @ViewChild setters such as replyCommentInput on post detail, home, forum, and profile.
  • Queries initialized with = null. The signal API does not allow that write.
  • The 10 leftover outputs. Alert modal and a couple of others still get .subscribe() or .pipe() on the EventEmitter.

Do not force those. The next person who wants 100% coverage needs to change the call sites first.

How I checked it

CheckResult
Main QA buildPass. About 57s. --prerender=false.
Perfect Crew QA buildNot run. This branch's angular.json only lists TopFans. Same src as a generated white-label would compile.
SSR200 on home, login, pricing, about, creators (curl). No Angular compile errors in the HTML.
Logged-out browserHome hydrates. Login form takes an email and the password toggle works. Pricing renders. Creators 504'd through the preview tunnel. Curl still got 200. That tunnel has been flaky before.
Logged-in productNot run.

Verification checklist

Creator account on a white-label site for logged-in checks. Private window for logged-out. Console open. Grouped by the modules in the 703-file diff. Shared and the primitives folder are the biggest chunks. If a modal opens through AlertModal, you are testing the leftover decorators on purpose.

0 of 0 checked

High Shared UI, header, posts

High Dashboard, wallet, messages

Medium Edit preference, portfolio, cover editor

Medium Auth, insights, monetize, profile layouts

Low Public pages, leftovers, white-label