This is a high risk change: every byte the card ships is emitted by a
different bundler, minified by a different minifier, and every
stylesheet is compiled by a different sass. The intent is that the
card's behaviour is unchanged.
**Significant development win**: Build time drops from 24s to 1.1s 🎉
Also adds a test suite ('dist') that runs against the built bundle.
2.9 KiB
2.9 KiB
Advanced Camera Card
Stack & Workflow
TypeScript (strict), Lit v3, Zod, Vitest, Vite, Yarn.
Commands: yarn install, yarn run build, yarn run test, yarn run coverage, yarn run format, yarn run lint, yarn run prune, yarn run docs-check-links.
Code Style
- Conventional Commits (used by semantic-release).
- Comments explain why, not what -- only when intent isn't obvious from code.
TypeScript
interfacefor object structures;typefor unions/intersections.- Never use
any; useunknown, generics, oras unknown as T. In tests, useassertfromvitestfor type narrowing. - Never use non-null assertions (
!); null-check with early return instead. noUnusedParametersandnoImplicitReturnsare enforced.- Return
null(notundefined) for absent values. async/awaitover.then()chains.Dateobjects over rawDate.now().
Testing
mock<T>()fromvitest-mock-extendedfor type-safe mocks.- Test files:
*.test.tsundertests/, mirroring source hierarchy. - 100% coverage required for:
camera-manager/,card-controller/,components-lib/,config/,conditions/,ha/,utils/,view/. Web components (components/*) exempt; push logic intocomponents-lib/controllers. - Reuse factories from
tests/test-utils.ts(createHASS(),createCameraConfig(), etc.). - Test names describe observable behavior, not internals.
Architecture
- Consolidate duplicate logic when adding helpers; don't leave redundant inline expressions.
- Naming consistency: Renames span all layers -- schema, types, CSS, localization keys, templates, docs. All schema fields must appear in the documentation table.
- Separation of concerns:
components/renders only; logic incomponents-lib/controllers (usingReactiveControllerwhere needed). - Manager pattern:
CardControllerorchestrates managers (ConfigManager,HASSManager,ViewManager, etc.). New cross-cutting concerns → new manager. - Module conventions:
types.tsfor types/schemas,*-manager.tsfor coordinators,*-controller.tsfor logic,utils/for helpers.
Preferences
- Think through UX states and edge cases before writing code.
- No re-exports or pass-through files -- import from source directly.
- Derive TypeScript types from Zod schemas (
z.infer<typeof schema>); no parallel interfaces. - User-facing schemas: only user-configurable fields. Internal fields go in a derived interface (
interface InternalFoo extends Foo { ... }). - Shared schemas go in
config/schema/common/from the start. - Name fields for semantic purpose, not implementation detail.
- Comment headings must reflect all items in the section.
- Verify CSS cascade (e.g.
pointer-events) before adding interactive children. - Preserve alphabetical ordering when inserting into sorted lists/sections.
- Prefer structural CSS selectors (
.parent child-element) over permanently-enabled classes.