Skip to content

Update Demo + Functionality Cleanups#2

Merged
StephenRiosDev merged 14 commits into
mainfrom
feat/update-demo
Feb 19, 2026
Merged

Update Demo + Functionality Cleanups#2
StephenRiosDev merged 14 commits into
mainfrom
feat/update-demo

Conversation

@StephenRiosDev
Copy link
Copy Markdown
Owner

@StephenRiosDev StephenRiosDev commented Feb 19, 2026

This may have gotten out of hand...

But as demos tend to do, this revealed some weaknesses in the existing implementation, and the dominos fell from there.

Who needs clean commit histories?

Greenfield is an exception, right? ;)

Anyways, great strides!

Summary by Sourcery

Introduce a new notification demo showcasing a four-level feature-based component hierarchy and refactor the Lit feature system to use a centralized resolver, unified metadata, and tighter integration with Lit’s lifecycle and property model.

New Features:

  • Add a notification demo app with message, message box, alert, and toast components that exercise the full feature composition and inheritance model.
  • Introduce Status, Visibility, Dismiss, and Timer features that compose behavior such as status styling, transitions, dismissal, and countdown timers.
  • Add a feature resolver that computes resolved feature configuration and properties across the inheritance chain using unified metadata.

Enhancements:

  • Refactor FeatureManager and LitCore to rely on resolved feature snapshots for instantiation and property merging instead of ad hoc inheritance scanning.
  • Unify feature-related decorator metadata (provide, configure, and feature properties) under a single FEATURE_META mechanism and simplify decorator exports.
  • Improve LitFeature’s integration with Lit by registering as a ReactiveController, refining host-feature property synchronization, and enhancing lifecycle hooks and logging.
  • Update base styling and HTML entry point to focus on the new notification demo experience.

Documentation:

  • Add a detailed PROPOSAL document describing the composable feature-centric controller architecture, design rationale, and integration plan with Lit.
  • Adjust the README to reflect the updated static feature APIs and decorator usage.

…sive

- Note: this revealed some bugs in the implementation regarding the inheritance chain, so functionality is broken. A fix is in progress.
…sive

- Updated demo to be more comprehensive with a message base > message box > alert box > toast notification progression
- Refactored approach for gathering provide and configure options to be lazy and deterministic rather than aggressive during register call.
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Feb 19, 2026

Reviewer's Guide

Refactors the Lit feature system to use a centralized feature resolver and unified metadata, introduces a full notification demo stack (message/alert/toast) powered by composable features (status, visibility, dismiss, timer), updates LitCore/FeatureManager wiring, and replaces the old demo and dark-theme styling with a notification-focused demo and light theme.

Sequence diagram for feature resolution and initialization on component registration

sequenceDiagram
  autonumber
  actor Dev as Developer
  participant MB as MessageBase_class
  participant FR as feature_resolver
  participant RF as ResolvedFeatures
  participant CE as customElements
  participant Inst as MessageBase_instance
  participant FM as FeatureManager
  participant SF as StatusFeature

  Dev->>MB: MessageBase.register("message-base")
  activate MB
  MB->>FR: resolveFeatures(MB)
  activate FR
  FR->>FR: getInheritanceChain(MB)
  FR->>FR: collect provide/config from
  FR->>FR: FEATURE_META and static_members
  FR->>RF: build ResolvedFeatures
  FR-->>MB: ResolvedFeatures
  deactivate FR

  MB->>MB: cache _resolvedFeatures
  MB->>CE: define("message-base", MB)
  deactivate MB

  Dev->>CE: new message-base()
  CE-->>Inst: construct instance
  activate Inst
  Inst->>FM: new FeatureManager(Inst, MB)
  activate FM
  FM->>FR: resolveFeatures(MB)
  FR-->>FM: ResolvedFeatures (from cache)
  FM->>FM: _initializeFeatures(ResolvedFeatures)
  FM->>SF: new StatusFeature(Inst, config)
  FM->>Inst: attach StatusFeature as Status
  FM->>Inst: map feature properties into host
  deactivate FM
  deactivate Inst
Loading

Updated class diagram for the core LitFeature system

classDiagram
  direction LR

  class LitElement {
  }

  class LitCore {
    <<component>>
    +FeatureManager featureManager
    +static properties Record~string,PropertyDeclaration~
    +static configure Record~string,FeatureConfigEntry_or_disable~
    +static provide Record~string,FeatureDefinition~
    +static finalize() void
    +static register(componentName string) void
  }

  class FeatureManager {
    -LitCore host
    -LitCoreConstructor hostConstructor
    -Map~string, LitFeature~ _featureInstances
    +constructor(host LitCore, constructor LitCoreConstructor)
    -_initializeFeatures(resolved ResolvedFeatures) void
  }

  class LitFeature {
    <<interface ReactiveController>>
    +LitCore host
    +FeatureConfig config
    -Map~string, unknown~ _internalValues
    +constructor(host LitCore, config FeatureConfig)
    +firstUpdated(changedProperties Map~PropertyKey,unknown~) void
    +updated(changedProperties Map~PropertyKey,unknown~) void
    +hostUpdated() void
    -_litFeatureInit() void
    -_createPropertyObserver(propertyName string) void
    +setInternalValue(propertyName string, value unknown) void
    +getInternalValue(propertyName string) unknown
  }

  class StatusFeature {
    +StatusType status
    +boolean showIcon
    +StatusStyles statusStyles
    +constructor(host LitCore, config StatusConfig)
    +getStatusIcon() string
    +getStatusColor() string
  }

  class VisibilityFeature {
    +boolean visible
    +boolean transitioning
    +constructor(host LitCore, config VisibilityConfig)
    +show() void
    +hide() void
    +toggle() void
    +getTransitionStyles() string
  }

  class DismissFeature {
    +boolean dismissible
    +boolean dismissed
    +constructor(host LitCore, config DismissConfig)
    +getDismissLabel() string
    +dismiss() boolean
  }

  class TimerFeature {
    +number duration
    +number remaining
    +number progress
    +boolean running
    +boolean paused
    +constructor(host LitCore, config TimerConfig)
    +start() void
    +pause() void
    +resume() void
    +reset() void
    +stop() void
    +getFormattedRemaining() string
  }

  class FeatureDefinition {
    +FeatureClass class
    +FeatureConfig config
    +boolean enabled
  }

  class FeatureConfigEntry {
    +FeatureConfig config
    +Record~string,PropertyDeclaration_or_disable~ properties
  }

  class FeatureMeta {
    +Map~string,FeatureDefinition~ provide
    +Map~string,FeatureConfigEntry_or_disable~ configure
    +Map~string,PropertyDeclaration~ featureProperties
  }

  class ResolvedFeatures {
    +Record~string,PropertyDeclaration~ properties
    +Map~string,ResolvedFeatureItem~ features
  }

  class ResolvedFeatureItem {
    +typeof_LitFeature class
    +FeatureConfig config
  }

  class LitCoreConstructor {
    +new() LitCore
    +string name
    +Record~string,FeatureDefinition~ provide
    +Record~string,FeatureConfigEntry_or_disable~ configure
    +Record~string,FeatureDefinition~ provides
    +Record~string,FeatureConfigEntry_or_disable~ features
    +Record~string,PropertyDeclaration~ properties
    +ResolvedFeatures _resolvedFeatures
    +Record~string,PropertyDeclaration~ _resolvedProperties
  }

  class FEATURE_META {
  }

  class LIT_CORE_MARKER {
  }

  class feature_resolver {
    +resolveFeatures(ctor LitCoreConstructor) ResolvedFeatures
  }

  LitElement <|-- LitCore
  LitCore o-- FeatureManager
  LitFeature <|-- StatusFeature
  LitFeature <|-- VisibilityFeature
  LitFeature <|-- DismissFeature
  LitFeature <|-- TimerFeature

  FeatureManager ..> ResolvedFeatures
  FeatureManager ..> LitFeature : creates
  feature_resolver ..> ResolvedFeatures
  feature_resolver ..> FeatureMeta
  feature_resolver ..> FeatureDefinition
  feature_resolver ..> FeatureConfigEntry

  LitCoreConstructor ..> ResolvedFeatures : caches
  LitCoreConstructor ..> FEATURE_META : reads
  LitCoreConstructor ..> LIT_CORE_MARKER : static_read

  LitCore ..> feature_resolver : resolveFeatures
  LitCore ..> LitCoreConstructor : static_finalize
  FeatureDefinition ..> LitFeature
  FeatureMeta ..> FeatureDefinition
  FeatureMeta ..> FeatureConfigEntry
  ResolvedFeatures --> ResolvedFeatureItem
Loading

Updated class diagram for the notification demo component hierarchy

classDiagram
  direction TB

  class LitCore {
  }

  class MessageBase {
    <<component>>
    +StatusFeature Status
    +StatusType status
    +boolean showIcon
    +StatusStyles statusStyles
    +renderContent() TemplateResult
    +render() TemplateResult
  }

  class MessageBox {
    <<component>>
    +VisibilityFeature Visibility
    +boolean visible
    +boolean transitioning
    +show() void
    +hide() void
    +toggle() void
    +render() TemplateResult
  }

  class AlertBox {
    <<component>>
    +DismissFeature Dismiss
    +boolean dismissible
    +boolean dismissed
    -_handleDismiss() void
    +render() TemplateResult
  }

  class ToastNotification {
    <<component>>
    +TimerFeature Timer
    +number duration
    +number remaining
    +number progress
    +boolean running
    +boolean paused
    +pauseTimer() void
    +resumeTimer() void
    +resetTimer() void
    -_startProgressTracking() void
    -_handleMouseEnter() void
    -_handleMouseLeave() void
    +render() TemplateResult
  }

  class NotificationDemo {
    <<component>>
    -number _toastCount
    -Array_toast_ _toasts
    -_createToast(status StatusType) void
    -_toggleMessageBox() void
    -_resetAlerts() void
    -_removeToast(id number) void
    +render() TemplateResult
  }

  class StatusFeature {
  }

  class VisibilityFeature {
  }

  class DismissFeature {
  }

  class TimerFeature {
  }

  class ToastItem {
    +number id
    +StatusType status
    +string message
  }

  LitCore <|-- MessageBase
  MessageBase <|-- MessageBox
  MessageBox <|-- AlertBox
  AlertBox <|-- ToastNotification

  MessageBase o-- StatusFeature
  MessageBox o-- VisibilityFeature
  AlertBox o-- DismissFeature
  ToastNotification o-- TimerFeature

  NotificationDemo o-- ToastNotification : renders_many
  NotificationDemo o-- MessageBase : demo_examples
  NotificationDemo o-- MessageBox : demo_examples
  NotificationDemo o-- AlertBox : demo_examples
  NotificationDemo --> ToastItem : manages_state
Loading

File-Level Changes

Change Details Files
Replace FeatureManager class-level resolution/config merging with a pure resolver module and make FeatureManager instance-only for feature instantiation and host attachment.
  • Remove static inheritance/configuration logic from FeatureManager and delegate all feature resolution to resolveFeatures()
  • Initialize FeatureManager with a pre-resolved ResolvedFeatures snapshot and only create/attach feature instances at the instance level
  • Simplify host attachment: warn on name conflicts and always attach the instance to either host[featureName] or host[_${featureName}] without registering feature-defined properties on the host here
src/root/services/feature-manager.ts
src/root/feature-resolver.ts
src/root/types/feature-types.ts
Change LitCore to integrate with the new resolver, using it during class finalization and registration to merge feature properties into Lit's reactive properties map and cache resolved state.
  • Introduce LIT_CORE_MARKER to identify LitCore-based classes for inheritance walking
  • Override LitCore.finalize() to call resolveFeatures(), merge resolved.properties with super/own properties, and then call super.finalize()
  • Replace old static _featureProperties/_featuresInitialized and prepareFeatures() flow with a simpler resolveFeatures() call in register() using new type aliases from feature-manager
src/root/lit-core.ts
src/root/services/feature-manager.ts
src/root/types/feature-types.ts
src/root/types/index.ts
Unify feature metadata storage for decorators and properties via FEATURE_META, and simplify @provide/@configure/@Property decorators to populate this metadata instead of bespoke registries.
  • Add FEATURE_META and getOrCreateFeatureMeta helper that stores provide, configure, and featureProperties maps on constructors
  • Rewrite provide() decorator to register definitions into meta.provide instead of PROVIDES_REGISTRY and remove exported registry helpers
  • Rewrite configure() decorator to register config entries into meta.configure instead of CONFIGURE_REGISTRY and remove inheritance helpers
  • Introduce a feature-property decorator that records PropertyDeclaration metadata into FeatureMeta.featureProperties and mirrors it into the feature class’s static properties for runtime proxies
  • Update decorator index exports to only expose provide, configure, ConfigureOptions, ProvideDefinition, and FEATURE_META
src/root/decorators/feature-meta.ts
src/root/decorators/feature-property.ts
src/root/decorators/provide.ts
src/root/decorators/configure.ts
src/root/decorators/index.ts
Enhance LitFeature to behave as a ReactiveController with improved host↔feature property synchronization and lifecycle integration.
  • Make LitFeature implement ReactiveController and register itself via host.addController() in the constructor
  • Change _litFeatureInit() to only create proxy accessors for declared properties and defer value reconciliation to lifecycle hooks
  • Update property setter to write to the host’s reactive property, mirror to internal storage, requestUpdate, and log diagnostics
  • Reimplement firstUpdated/updated to sync values between host and feature based on changedProperties, with host winning on conflicts and updated only syncing changed keys
  • Add an empty hostUpdated() hook documenting that host→feature sync is driven via FeatureManager lifecycle wiring
src/root/lit-feature.ts
Introduce a multi-level notification demo (message-base → message-box → alert-box → toast-notification) showcasing composable features for status, visibility, dismiss, and timer behaviors.
  • Add MessageBase that provides StatusFeature and renders basic styled messages with icons and status variants
  • Add MessageBox extending MessageBase, providing VisibilityFeature, wiring show/hide/toggle and transition styles into the template
  • Add AlertBox extending MessageBox, providing DismissFeature, and rendering a dismiss button integrated with visibility transitions
  • Add ToastNotification extending AlertBox, providing TimerFeature, showing progress bar, timer controls, and coordinating auto-dismiss with DismissFeature
  • Create NotificationDemo shell component that renders all four levels, manages toast instances via state, and demonstrates feature inheritance and configuration overrides
src/components/message-base.ts
src/components/message-box.ts
src/components/alert-box.ts
src/components/toast-notification.ts
src/components/notification-demo.ts
src/features/status-feature.ts
src/features/visibility-feature.ts
src/features/dismiss-feature.ts
src/features/timer-feature.ts
Adjust documentation and public types to match the new feature API and rename configuration statics in the README demo to match the current proposal.
  • Rewrite README usage sections to refer to static provides/features instead of provide/configure, and to map decorators onto these names
  • Adjust docs to describe the four example features and the lack of explicit "feature enabled" switches in static features()
  • Add a detailed PROPOSAL.md describing the composable feature-centric controller architecture, lifecycle, integration plan, and open questions
  • Update exported types to drop old ProvidesRegistry/FeaturesRegistry and surface FeatureMeta/ResolvedFeatures instead
readme.md
PROPOSAL.md
src/root/types/index.ts
Swap the old dark-theme feature demo shell for the new notification demo and refresh global styling for a light, centered layout suitable for the notification showcase.
  • Change index.html to load notification-demo.ts and render instead of the previous feature-demo element
  • Update index.css to use a light background, system font stack, and body padding instead of a centered flex layout and dark theme
  • Remove obsolete demo components and features that are no longer used by the new notification demo
index.html
index.css
src/components/custom-element.ts
src/components/feature-demo.ts
src/features/counter-feature.ts
src/features/focus-feature.ts
src/features/layout-feature.ts
src/features/lifecycle-logger-feature.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

sourcery-ai[bot]

This comment was marked as resolved.

This comment was marked as resolved.

StephenRiosDev and others added 7 commits February 19, 2026 10:53
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- Implemented a PerformanceMonitor to track and log performance metrics for component initialization and rendering.
- Created StressTest component to generate and monitor 50+ components for performance bottlenecks.
- Developed SuperStressTest component to silently generate 500 complex components for performance evaluation.
- Added HTML files for both StressTest and SuperStressTest components to facilitate testing in a browser environment.
- Enhanced existing LitCore and LitFeature classes to integrate performance monitoring during construction and feature initialization.
@StephenRiosDev StephenRiosDev merged commit 31a97c3 into main Feb 19, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants