@hawsen-the-first/interactiv 0.0.2 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -15,6 +15,7 @@ import { Logger } from "./utils/logger";
15
15
  import { useAnimations, AnimationManager } from "./src/animationBus";
16
16
  import { configureLogger } from "./src/logger";
17
17
  import { GarbageCollector, createGarbageCollector, type GarbageCollectionStats } from "./src/garbageCollector";
18
- export { createOrchestrator, EventOrchestrator, EventBus, AppBuilder, Page, View, Component, NavigationManager, ScreensaverManager, SettingsManager, EventManager, AnimationManager, stateManager, getGlobalState, setGlobalState, subscribeToGlobalState, useGlobalStateExternal, useAnimations, ExternalStateManager, ComponentStateManager, GarbageCollector, createGarbageCollector, css, html, Logger, configureLogger, };
19
- export type { PointerEventData, DragCallbacks, HoverCallbacks, SwipeCallbacks, StateSubscription, ScreensaverConfig, SettingsConfig, PageProps, ViewProps, ComponentProps, GarbageCollectionStats, };
18
+ import { TransitionOverlay, transitionWithOverlay, type TransitionOverlayConfig, type TransitionRequestPayload } from "./src/transitionOverlay";
19
+ export { createOrchestrator, EventOrchestrator, EventBus, AppBuilder, Page, View, Component, NavigationManager, ScreensaverManager, SettingsManager, EventManager, AnimationManager, stateManager, getGlobalState, setGlobalState, subscribeToGlobalState, useGlobalStateExternal, useAnimations, ExternalStateManager, ComponentStateManager, GarbageCollector, createGarbageCollector, TransitionOverlay, transitionWithOverlay, css, html, Logger, configureLogger, };
20
+ export type { PointerEventData, DragCallbacks, HoverCallbacks, SwipeCallbacks, StateSubscription, ScreensaverConfig, SettingsConfig, PageProps, ViewProps, ComponentProps, GarbageCollectionStats, TransitionOverlayConfig, TransitionRequestPayload, };
20
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,cAAc,EACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,KAAK,sBAAsB,EAC5B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACV,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAEhB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EAErB,gBAAgB,EAChB,sBAAsB,EACtB,GAAG,EACH,IAAI,EACJ,MAAM,EACN,eAAe,GAChB,CAAC;AAEF,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,SAAS,EACT,cAAc,EACd,sBAAsB,GACvB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACjF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,YAAY,EACZ,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,cAAc,EACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,KAAK,sBAAsB,EAC5B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC9B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,EACR,UAAU,EACV,IAAI,EACJ,IAAI,EACJ,SAAS,EACT,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,gBAAgB,EAEhB,YAAY,EACZ,cAAc,EACd,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,qBAAqB,EAErB,gBAAgB,EAChB,sBAAsB,EAEtB,iBAAiB,EACjB,qBAAqB,EACrB,GAAG,EACH,IAAI,EACJ,MAAM,EACN,eAAe,GAChB,CAAC;AAEF,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,SAAS,EACT,cAAc,EACd,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,GACzB,CAAC"}
package/dist/index.js CHANGED
@@ -10,12 +10,15 @@ import { Logger } from "./utils/logger";
10
10
  import { useAnimations, AnimationManager } from "./src/animationBus";
11
11
  import { configureLogger } from "./src/logger";
12
12
  import { GarbageCollector, createGarbageCollector, } from "./src/garbageCollector";
13
+ import { TransitionOverlay, transitionWithOverlay, } from "./src/transitionOverlay";
13
14
  5;
14
15
  export { createOrchestrator, EventOrchestrator, EventBus, AppBuilder, Page, View, Component, NavigationManager, ScreensaverManager, SettingsManager, EventManager, AnimationManager,
15
16
  // External State Management
16
17
  stateManager, getGlobalState, setGlobalState, subscribeToGlobalState, useGlobalStateExternal, useAnimations, ExternalStateManager, ComponentStateManager,
17
18
  // Garbage Collection
18
- GarbageCollector, createGarbageCollector, css, html, Logger, configureLogger, };
19
+ GarbageCollector, createGarbageCollector,
20
+ // Transition Overlay System
21
+ TransitionOverlay, transitionWithOverlay, css, html, Logger, configureLogger, };
19
22
  // Named exports for direct import
20
23
  // export {
21
24
  // stateManager,
@@ -5,6 +5,7 @@ import { EventManager } from "./eventManager";
5
5
  import { ComponentStateManager } from "./stateManager";
6
6
  import type { PointerEventData, DragCallbacks, HoverCallbacks, SwipeCallbacks } from "./eventManager";
7
7
  import type { RenderOptions } from "./types";
8
+ import { TransitionOverlay, type TransitionOverlayConfig } from "./transitionOverlay";
8
9
  declare abstract class RenderableComponent {
9
10
  componentId: string;
10
11
  state: any;
@@ -139,11 +140,42 @@ declare class AppBuilder extends RenderableComponent {
139
140
  }
140
141
  declare class Page extends RenderableComponent {
141
142
  private views;
143
+ private transitionOverlay;
144
+ private transitionBus;
142
145
  constructor(id: string, orchestrator: EventOrchestrator, bubbleChanges?: boolean, customTemplate?: string, customStyles?: string);
143
146
  protected defineTemplate(): void;
144
147
  protected defineStyles(): void;
145
148
  addView(view: View): void;
146
149
  removeView(viewId: string): void;
150
+ /**
151
+ * Enable transition overlay for this page
152
+ *
153
+ * Creates a full-screen overlay that fades in/out to hide content changes during state updates.
154
+ * Once enabled, components can request transitions via the "page-transition-overlay" event bus.
155
+ *
156
+ * @param config - Configuration for the overlay appearance and timing
157
+ */
158
+ useTransitionOverlay(config: TransitionOverlayConfig): void;
159
+ /**
160
+ * Execute a callback wrapped in the transition overlay lifecycle
161
+ *
162
+ * This is a convenience method for direct Page-level access to the overlay.
163
+ * For deeply nested components, prefer using the standalone `transitionWithOverlay` utility
164
+ * or emitting to the "page-transition-overlay" event bus.
165
+ *
166
+ * @param callback - Function to execute while overlay is opaque (state changes happen here)
167
+ * @returns Promise that resolves after the full transition completes
168
+ * @throws Error if useTransitionOverlay() hasn't been called
169
+ */
170
+ transitionWithOverlay(callback: () => void | Promise<void>): Promise<void>;
171
+ /**
172
+ * Check if this page has a transition overlay enabled
173
+ */
174
+ hasTransitionOverlay(): boolean;
175
+ /**
176
+ * Get the TransitionOverlay instance for this page (for NavigationManager integration)
177
+ */
178
+ getTransitionOverlay(): TransitionOverlay | null;
147
179
  /**
148
180
  * Add a screensaver page with the specified configuration.
149
181
  * Pass `null` for screensaverPage when using `screensaverViewBehavior: "returnHome"` mode,
@@ -1 +1 @@
1
- {"version":3,"file":"appBuilder.d.ts","sourceRoot":"","sources":["../../src/appBuilder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"appBuilder.d.ts","sourceRoot":"","sources":["../../src/appBuilder.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,7 @@ import { SettingsManager } from "./settingsManager";
6
6
  import { EventManager } from "./eventManager";
7
7
  import { ComponentStateManager } from "./stateManager";
8
8
  import { logger } from "./logger";
9
+ import { TransitionOverlay, stateChangesToCallback, } from "./transitionOverlay";
9
10
  class RenderableComponent {
10
11
  componentId;
11
12
  state;
@@ -538,6 +539,8 @@ class AppBuilder extends RenderableComponent {
538
539
  // Page - Contains Views
539
540
  class Page extends RenderableComponent {
540
541
  views = [];
542
+ transitionOverlay = null;
543
+ transitionBus = null;
541
544
  constructor(id, orchestrator, bubbleChanges = true, customTemplate, customStyles) {
542
545
  super(id, orchestrator, bubbleChanges);
543
546
  // Set custom template/styles before initial render if provided
@@ -647,6 +650,96 @@ class Page extends RenderableComponent {
647
650
  this.removeChild(viewId);
648
651
  }
649
652
  }
653
+ /**
654
+ * Enable transition overlay for this page
655
+ *
656
+ * Creates a full-screen overlay that fades in/out to hide content changes during state updates.
657
+ * Once enabled, components can request transitions via the "page-transition-overlay" event bus.
658
+ *
659
+ * @param config - Configuration for the overlay appearance and timing
660
+ */
661
+ useTransitionOverlay(config) {
662
+ if (this.transitionOverlay) {
663
+ logger.warn(`Page ${this.componentId} already has a transition overlay configured`);
664
+ return;
665
+ }
666
+ // Create the transition overlay
667
+ this.transitionOverlay = new TransitionOverlay(config, this.shadowRoot);
668
+ // Register the event bus for transition requests
669
+ this.transitionBus = this.orchestrator.registerEventBus("page-transition-overlay");
670
+ // Listen for transition requests
671
+ this.transitionBus.on("request-transition", async (e) => {
672
+ const payload = e.detail;
673
+ try {
674
+ // Build the callback from state changes or use provided callback
675
+ let callback;
676
+ if (payload.callback) {
677
+ // Direct callback provided (from standalone utility)
678
+ callback = payload.callback;
679
+ }
680
+ else if (payload.stateChanges) {
681
+ // State changes array provided (from consumer usage)
682
+ callback = async () => {
683
+ stateChangesToCallback(payload.stateChanges)();
684
+ // Execute afterStateChange if provided
685
+ if (payload.afterStateChange) {
686
+ await Promise.resolve(payload.afterStateChange());
687
+ }
688
+ };
689
+ }
690
+ else {
691
+ throw new Error("Transition request must include either 'callback' or 'stateChanges'");
692
+ }
693
+ // Execute the transition with config overrides
694
+ await this.transitionOverlay.executeTransition(callback, {
695
+ fadeInDuration: payload.fadeInDuration,
696
+ holdDuration: payload.holdDuration,
697
+ fadeOutDuration: payload.fadeOutDuration,
698
+ });
699
+ // Resolve the promise if provided (from standalone utility)
700
+ if (payload._resolve) {
701
+ payload._resolve();
702
+ }
703
+ }
704
+ catch (error) {
705
+ logger.error("Transition overlay error:", error);
706
+ // Reject the promise if provided (from standalone utility)
707
+ if (payload._reject) {
708
+ payload._reject(error);
709
+ }
710
+ }
711
+ });
712
+ logger.trace(`Transition overlay enabled for page ${this.componentId}`);
713
+ }
714
+ /**
715
+ * Execute a callback wrapped in the transition overlay lifecycle
716
+ *
717
+ * This is a convenience method for direct Page-level access to the overlay.
718
+ * For deeply nested components, prefer using the standalone `transitionWithOverlay` utility
719
+ * or emitting to the "page-transition-overlay" event bus.
720
+ *
721
+ * @param callback - Function to execute while overlay is opaque (state changes happen here)
722
+ * @returns Promise that resolves after the full transition completes
723
+ * @throws Error if useTransitionOverlay() hasn't been called
724
+ */
725
+ async transitionWithOverlay(callback) {
726
+ if (!this.transitionOverlay) {
727
+ throw new Error(`Page ${this.componentId} does not have a transition overlay. Call useTransitionOverlay() first.`);
728
+ }
729
+ return this.transitionOverlay.executeTransition(callback);
730
+ }
731
+ /**
732
+ * Check if this page has a transition overlay enabled
733
+ */
734
+ hasTransitionOverlay() {
735
+ return this.transitionOverlay !== null;
736
+ }
737
+ /**
738
+ * Get the TransitionOverlay instance for this page (for NavigationManager integration)
739
+ */
740
+ getTransitionOverlay() {
741
+ return this.transitionOverlay;
742
+ }
650
743
  /**
651
744
  * Add a screensaver page with the specified configuration.
652
745
  * Pass `null` for screensaverPage when using `screensaverViewBehavior: "returnHome"` mode,
@@ -18,8 +18,7 @@ export declare class EventBus<DetailType = any> {
18
18
  * Destroy this event bus and clean up all listeners
19
19
  */
20
20
  destroy(): void;
21
- emit(type: string, detail?: DetailType): boolean | undefined;
22
- private validateEventDispatch;
21
+ emit(type: string, detail?: DetailType): boolean;
23
22
  }
24
23
  export declare class EventOrchestrator {
25
24
  private eventBuses;
@@ -1 +1 @@
1
- {"version":3,"file":"eventBus.d.ts","sourceRoot":"","sources":["../../src/eventBus.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eventBus.d.ts","sourceRoot":"","sources":["../../src/eventBus.ts"],"names":[],"mappings":"AAMA,qBAAa,QAAQ,CAAC,UAAU,GAAG,GAAG;IACpC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,EAAE,CAAS;gBACP,WAAW,SAAc;IAIrC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,KAAK,IAAI;IAiBnE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC,KAAK,IAAI;IAiBrE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAmB1B;;OAEG;IACH,SAAS,IAAI,IAAI;IAQjB;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACH,OAAO,IAAI,IAAI;IASf,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,UAAU;CAgBvC;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,YAAY,CAAkB;IACtC,OAAO,CAAC,gBAAgB,CAAQ;IAChC,OAAO,CAAC,aAAa,CAAW;;IAUhC,GAAG;IAqBH,gBAAgB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC;IAM9C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAI1C,OAAO,CACL,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAkB,EAC5B,MAAM,CAAC,EAAE,OAAO,EAChB,WAAW,CAAC,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,MAAM;IAWjB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,yBAAyB;IAIzD,OAAO,CAAC,4BAA4B;IAKpC,qBAAqB,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAG5D,OAAO;IAIP,cAAc,CAAC,WAAW,EAAE,GAAG;IAY/B,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,4BAA4B;IAwDpC;;;OAGG;IACI,oBAAoB,IAAI,MAAM;IAmBrC;;OAEG;IACI,YAAY,IAAI,MAAM;IAI7B;;OAEG;IACI,gBAAgB,IAAI,MAAM;IAIjC;;OAEG;IACI,qBAAqB,IAAI,MAAM;IAMtC;;;;;;OAMG;IACI,cAAc,CACnB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;QAC9D,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC;QAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,EACD,QAAQ,GAAE,MAAoB,GAC7B,IAAI;IAOP;;;;;;OAMG;IACI,cAAc,CACnB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE;QACP,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;QAC9D,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC;QAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,EACD,QAAQ,GAAE,MAAoB,GAC7B,IAAI;CAMR;AACD,cAAM,yBAAyB;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;gBAGtB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAkB,EAC5B,WAAW,GAAE,MAAmB,EAChC,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,OAAO;CAUnB;AAED,wBAAgB,kBAAkB,sBAEjC"}
@@ -86,24 +86,12 @@ export class EventBus {
86
86
  log.trace(`Event Bus ${this.id} destroyed`);
87
87
  }
88
88
  emit(type, detail) {
89
- try {
90
- this.validateEventDispatch(type);
91
- return this.eventTarget.dispatchEvent(new CustomEvent(type, { detail }));
92
- }
93
- catch (error) {
94
- log.error(error.message, error);
95
- }
96
- }
97
- // private validateNewListener(type: string): void {
98
- // // Allow multiple listeners for the same event type
99
- // // This validation is too restrictive for our use case
100
- // // Components may need to register multiple listeners for the same event
101
- // return;
102
- // }
103
- validateEventDispatch(type) {
89
+ // Check if there are any listeners before dispatching
104
90
  if (this.activeListeners.filter((l) => l.eventName === type).length === 0) {
105
- throw new Error(`Failed to dispatch event. Event Bus with Id ${this.id} does not contain a listener for an event with the name ${type}`);
91
+ log.trace(`Event Bus [${this.id}]: No listeners registered for event "${type}", skipping dispatch.`);
92
+ return true; // Return true to indicate the event was "handled" (just not dispatched)
106
93
  }
94
+ return this.eventTarget.dispatchEvent(new CustomEvent(type, { detail }));
107
95
  }
108
96
  }
109
97
  export class EventOrchestrator {
@@ -66,6 +66,10 @@ export declare class NavigationManager {
66
66
  private performPageNavigationInternal;
67
67
  private performViewNavigationInternal;
68
68
  private performPageTransition;
69
+ /**
70
+ * Perform an immediate view swap (no animation) - used when transition overlay is handling the fade
71
+ */
72
+ private performViewSwapImmediate;
69
73
  private performViewTransition;
70
74
  private animateOut;
71
75
  private animateIn;
@@ -1 +1 @@
1
- {"version":3,"file":"navigationManager.d.ts","sourceRoot":"","sources":["../../src/navigationManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAgB,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAKtE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC9D,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IACzD,OAAO,CAAC,MAAM,CAAC,WAAW,CAAkB;IAE5C,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,kBAAkB,CAA2B;IACrD,OAAO,CAAC,wBAAwB,CAA2C;IAE3E;;;OAGG;WACW,WAAW,IAAI,iBAAiB,GAAG,IAAI;gBAIzC,YAAY,EAAE,iBAAiB;IA4B3C,OAAO,CAAC,qBAAqB;IAa7B,OAAO,CAAC,mBAAmB;IAsBpB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAa9B,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAQrC,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,kBAAkB;IAMb,cAAc,CACzB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,gBAAmC,EAC3C,QAAQ,GAAE,MAAoB,GAC7B,OAAO,CAAC,IAAI,CAAC;IAYH,cAAc,CACzB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,gBAAmC,EAC3C,QAAQ,GAAE,MAAoB,GAC7B,OAAO,CAAC,IAAI,CAAC;YAYF,6BAA6B;YA6B7B,6BAA6B;YAgC7B,qBAAqB;YAmBrB,qBAAqB;YAqBrB,UAAU;YAuEV,SAAS;IA2FvB,OAAO,CAAC,yBAAyB;IAkBjC,OAAO,CAAC,qBAAqB;IAwB7B,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,QAAQ;IAchB,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,YAAY;IAQb,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,gBAAgB,IAAI,MAAM,GAAG,IAAI;IAIjC,eAAe,IAAI,OAAO;IAI1B,kBAAkB,IAAI,MAAM,EAAE;IAI9B,kBAAkB,IAAI,MAAM,EAAE;IAK9B,sBAAsB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,iBAAiB;IAIpF,sBAAsB,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,iBAAiB;IAIpF,0BAA0B,CAAC,QAAQ,EAAE,CAAC,eAAe,EAAE,OAAO,KAAK,IAAI,GAAG,iBAAiB;IAIlG;;;OAGG;IACI,0BAA0B,IAAI,IAAI;IAezC;;OAEG;IACI,wBAAwB,IAAI,MAAM;IAIzC;;;;;;OAMG;IACI,OAAO,IAAI,IAAI;CAoBvB"}
1
+ {"version":3,"file":"navigationManager.d.ts","sourceRoot":"","sources":["../../src/navigationManager.ts"],"names":[],"mappings":"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"}
@@ -181,13 +181,35 @@ export class NavigationManager {
181
181
  log.trace(`Starting navigation from ${previousViewId} to ${viewId}`);
182
182
  stateManager.set("navigation.isTransitioning", true);
183
183
  try {
184
- await this.performViewTransition(viewId, config);
185
- stateManager.set("navigation.currentViewId", viewId);
186
- this.eventBus.emit("view-changed", {
187
- newViewId: viewId,
188
- previousViewId,
189
- });
190
- log.trace(`Navigation to ${viewId} completed successfully`);
184
+ // Check if current page has a transition overlay
185
+ const currentPageId = stateManager.get("navigation.currentPageId");
186
+ const currentPage = currentPageId ? this.pages.get(currentPageId) : null;
187
+ const hasOverlay = currentPage && currentPage.hasTransitionOverlay();
188
+ if (hasOverlay) {
189
+ // Use the overlay to wrap the view transition
190
+ log.trace(`Using transition overlay for view navigation to ${viewId}`);
191
+ const overlay = currentPage.getTransitionOverlay();
192
+ await overlay.executeTransition(async () => {
193
+ // Perform the view swap while overlay is opaque
194
+ await this.performViewSwapImmediate(viewId, previousViewId);
195
+ stateManager.set("navigation.currentViewId", viewId);
196
+ });
197
+ this.eventBus.emit("view-changed", {
198
+ newViewId: viewId,
199
+ previousViewId,
200
+ });
201
+ log.trace(`Navigation to ${viewId} completed successfully with overlay`);
202
+ }
203
+ else {
204
+ // No overlay - use standard transition
205
+ await this.performViewTransition(viewId, config);
206
+ stateManager.set("navigation.currentViewId", viewId);
207
+ this.eventBus.emit("view-changed", {
208
+ newViewId: viewId,
209
+ previousViewId,
210
+ });
211
+ log.trace(`Navigation to ${viewId} completed successfully`);
212
+ }
191
213
  }
192
214
  catch (error) {
193
215
  log.error(`Navigation to ${viewId} failed:`, error);
@@ -211,6 +233,23 @@ export class NavigationManager {
211
233
  }
212
234
  await this.animateIn(targetPage.getHostElement(), normalizedConfig);
213
235
  }
236
+ /**
237
+ * Perform an immediate view swap (no animation) - used when transition overlay is handling the fade
238
+ */
239
+ async performViewSwapImmediate(targetViewId, currentViewId) {
240
+ const currentView = currentViewId ? this.views.get(currentViewId) : null;
241
+ const targetView = this.views.get(targetViewId);
242
+ // Hide current view immediately
243
+ if (currentView) {
244
+ this.hideView(currentViewId);
245
+ }
246
+ // Show target view immediately (no animation since overlay handles the fade)
247
+ this.showView(targetViewId, false);
248
+ const element = targetView.getHostElement();
249
+ element.style.opacity = "1";
250
+ element.style.visibility = "visible";
251
+ element.style.transform = "none";
252
+ }
214
253
  async performViewTransition(targetViewId, config) {
215
254
  const currentViewId = stateManager.get("navigation.currentViewId");
216
255
  const currentView = currentViewId ? this.views.get(currentViewId) : null;
@@ -32,7 +32,10 @@ export declare class ScreensaverManager {
32
32
  private lastScreensaverViewId;
33
33
  private lastActivityResetTime;
34
34
  private globalListeners;
35
+ private interactionShieldActive;
36
+ private shieldRemovalTimer;
35
37
  private readonly DEBOUNCE_INTERVAL;
38
+ private readonly SHIELD_DURATION;
36
39
  private readonly DEFAULT_ACTIVITY_EVENTS;
37
40
  constructor(orchestrator: EventOrchestrator, navigationManager: NavigationManager);
38
41
  private initializeGlobalState;
@@ -69,5 +72,15 @@ export declare class ScreensaverManager {
69
72
  private checkAndPerformReboot;
70
73
  private startRebootCheckInterval;
71
74
  private stopRebootCheckInterval;
75
+ /**
76
+ * Activates the interaction shield to block follow-up events from the same gesture
77
+ * that dismissed the screensaver. This prevents touch events from bleeding through
78
+ * to elements on the home page.
79
+ */
80
+ private activateInteractionShield;
81
+ /**
82
+ * Deactivates the interaction shield, allowing normal event processing to resume.
83
+ */
84
+ private deactivateInteractionShield;
72
85
  }
73
86
  //# sourceMappingURL=screensaverManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"screensaverManager.d.ts","sourceRoot":"","sources":["../../src/screensaverManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAM/E,MAAM,WAAW,iBAAiB;IAChC,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uBAAuB,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,YAAY,CAAC;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,YAAY,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAChC,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,mBAAmB,CAAkB;IAC7C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,gBAAgB,CAAuB;IAC/C,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,eAAe,CAIf;IAGR,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAQ;IAG1C,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAStC;gBAEU,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB;IASjF,OAAO,CAAC,qBAAqB;IAkB7B,OAAO,CAAC,mBAAmB;IAyCpB,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAyC3D,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,cAAc;IAkCtB,OAAO,CAAC,4BAA4B;IAmDpC,OAAO,CAAC,oBAAoB;IAgB5B,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,kBAAkB;YAOZ,mBAAmB;IA6DjC;;;;OAIG;YACW,kBAAkB;IAkDhC,OAAO,CAAC,wBAAwB;YAclB,qBAAqB;YAmDrB,qBAAqB;IAI5B,QAAQ,IAAI,OAAO;IAInB,gBAAgB,IAAI,iBAAiB,GAAG,IAAI;IAI5C,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAIpC,mBAAmB,IAAI,MAAM,GAAG,IAAI;IAIpC,wBAAwB,IAAI,MAAM,GAAG,IAAI;IAKzC,aAAa,IAAI,IAAI;IAKrB,eAAe,IAAI,IAAI;IAIvB,UAAU,IAAI,IAAI;IAMzB,OAAO,CAAC,OAAO;IAcR,OAAO,IAAI,IAAI;IAUtB,OAAO,CAAC,uBAAuB;IAc/B,OAAO,CAAC,qBAAqB;IAc7B,OAAO,CAAC,wBAAwB;IAchC,OAAO,CAAC,uBAAuB;CAOhC"}
1
+ {"version":3,"file":"screensaverManager.d.ts","sourceRoot":"","sources":["../../src/screensaverManager.ts"],"names":[],"mappings":"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"}
@@ -14,8 +14,13 @@ export class ScreensaverManager {
14
14
  lastScreensaverViewId = null;
15
15
  lastActivityResetTime = null;
16
16
  globalListeners = [];
17
+ // Interaction shield state
18
+ interactionShieldActive = false;
19
+ shieldRemovalTimer = null;
17
20
  // Debounce interval for activity timer resets (in milliseconds)
18
21
  DEBOUNCE_INTERVAL = 1000;
22
+ // Shield duration to block follow-up events from the same gesture (in milliseconds)
23
+ SHIELD_DURATION = 400;
19
24
  // Default activity events to monitor
20
25
  DEFAULT_ACTIVITY_EVENTS = [
21
26
  "mousemove",
@@ -156,6 +161,13 @@ export class ScreensaverManager {
156
161
  if (!this.config)
157
162
  return;
158
163
  const activityHandler = (event) => {
164
+ // Block all events if interaction shield is active
165
+ if (this.interactionShieldActive) {
166
+ event.stopPropagation();
167
+ event.preventDefault();
168
+ log.trace(`Interaction shield blocked ${event.type} event`);
169
+ return;
170
+ }
159
171
  // Check if event should be ignored based on excludeSelectors
160
172
  if (this.shouldIgnoreActivity(event)) {
161
173
  return;
@@ -174,9 +186,14 @@ export class ScreensaverManager {
174
186
  }
175
187
  };
176
188
  // Add listeners to document for global coverage
189
+ // Use non-passive listeners for click and touch events to allow preventDefault()
177
190
  this.config.activityEvents.forEach((eventType) => {
178
191
  const listener = activityHandler.bind(this);
179
- document.addEventListener(eventType, listener, { passive: true });
192
+ const usePassive = !["click", "touchstart", "touchend"].includes(eventType);
193
+ document.addEventListener(eventType, listener, {
194
+ passive: usePassive,
195
+ capture: true // Use capture phase to intercept events before they reach targets
196
+ });
180
197
  this.globalListeners.push({
181
198
  element: document,
182
199
  type: eventType,
@@ -356,6 +373,8 @@ export class ScreensaverManager {
356
373
  if (!this.config || !this.isScreensaverActive)
357
374
  return;
358
375
  log.trace(`Exiting screensaver with '${this.config.exitBehavior}' behavior`);
376
+ // Activate interaction shield to block follow-up events from the same gesture
377
+ this.activateInteractionShield();
359
378
  // Stop the reboot check interval
360
379
  this.stopRebootCheckInterval();
361
380
  if (this.config.deactivateCallback)
@@ -432,6 +451,7 @@ export class ScreensaverManager {
432
451
  cleanup() {
433
452
  this.clearActivityTimer();
434
453
  this.stopRebootCheckInterval();
454
+ this.deactivateInteractionShield();
435
455
  // Remove all global event listeners
436
456
  this.globalListeners.forEach(({ element, type, listener }) => {
437
457
  element.removeEventListener(type, listener);
@@ -490,4 +510,34 @@ export class ScreensaverManager {
490
510
  log.trace("Reboot check interval stopped");
491
511
  }
492
512
  }
513
+ // Interaction shield methods
514
+ /**
515
+ * Activates the interaction shield to block follow-up events from the same gesture
516
+ * that dismissed the screensaver. This prevents touch events from bleeding through
517
+ * to elements on the home page.
518
+ */
519
+ activateInteractionShield() {
520
+ // Clear any existing shield timer
521
+ if (this.shieldRemovalTimer !== null) {
522
+ clearTimeout(this.shieldRemovalTimer);
523
+ this.shieldRemovalTimer = null;
524
+ }
525
+ this.interactionShieldActive = true;
526
+ log.trace("Interaction shield activated");
527
+ // Automatically deactivate shield after the gesture completes
528
+ this.shieldRemovalTimer = window.setTimeout(() => {
529
+ this.deactivateInteractionShield();
530
+ }, this.SHIELD_DURATION);
531
+ }
532
+ /**
533
+ * Deactivates the interaction shield, allowing normal event processing to resume.
534
+ */
535
+ deactivateInteractionShield() {
536
+ if (this.shieldRemovalTimer !== null) {
537
+ clearTimeout(this.shieldRemovalTimer);
538
+ this.shieldRemovalTimer = null;
539
+ }
540
+ this.interactionShieldActive = false;
541
+ log.trace("Interaction shield deactivated");
542
+ }
493
543
  }
@@ -0,0 +1,96 @@
1
+ import { EventOrchestrator } from "./eventBus";
2
+ export interface TransitionOverlayConfig {
3
+ backgroundColor?: string;
4
+ fadeInDuration?: number;
5
+ holdDuration?: number;
6
+ fadeOutDuration?: number;
7
+ zIndex?: number;
8
+ }
9
+ export interface TransitionRequestPayload {
10
+ stateChanges?: Array<{
11
+ key: string;
12
+ value: any;
13
+ }>;
14
+ afterStateChange?: () => void | Promise<void>;
15
+ fadeInDuration?: number;
16
+ holdDuration?: number;
17
+ fadeOutDuration?: number;
18
+ }
19
+ type TransitionPhase = "idle" | "fade-in" | "hold" | "fade-out";
20
+ /**
21
+ * TransitionOverlay - Manages visual overlay transitions for seamless content updates
22
+ *
23
+ * This class provides a fade-to-opaque overlay that hides content changes during state updates.
24
+ *
25
+ * **Concurrency Strategy:**
26
+ * - If a transition is in the **fade-in or hold phase**, incoming requests queue their callbacks
27
+ * to be batched into the current cycle's hold phase
28
+ * - If a transition is in the **fade-out phase**, incoming requests start a new transition cycle
29
+ * after the current one completes
30
+ *
31
+ * This ensures smooth transitions without jarring interruptions or visible content changes.
32
+ */
33
+ export declare class TransitionOverlay {
34
+ private config;
35
+ private shadowRoot;
36
+ private overlayElement;
37
+ private currentPhase;
38
+ private queuedCallbacks;
39
+ private queuedRequests;
40
+ private activeTransitionPromise;
41
+ constructor(config: TransitionOverlayConfig, shadowRoot: ShadowRoot);
42
+ private injectOverlayElement;
43
+ /**
44
+ * Execute a transition with the overlay lifecycle
45
+ *
46
+ * @param callback - Function to execute while overlay is opaque (state changes happen here)
47
+ * @param configOverrides - Optional per-request config overrides
48
+ * @returns Promise that resolves after the full transition completes
49
+ */
50
+ executeTransition(callback: () => void | Promise<void>, configOverrides?: Partial<TransitionOverlayConfig>): Promise<void>;
51
+ private handleConcurrentRequest;
52
+ private performTransition;
53
+ private fadeIn;
54
+ private executeCallbacks;
55
+ private fadeOut;
56
+ private processQueuedRequests;
57
+ /**
58
+ * Update the overlay configuration
59
+ */
60
+ updateConfig(config: Partial<TransitionOverlayConfig>): void;
61
+ /**
62
+ * Get the current transition phase
63
+ */
64
+ getPhase(): TransitionPhase;
65
+ /**
66
+ * Check if a transition is currently active
67
+ */
68
+ isTransitioning(): boolean;
69
+ /**
70
+ * Clean up the overlay element and resources
71
+ */
72
+ destroy(): void;
73
+ }
74
+ /**
75
+ * Standalone utility for requesting overlay transitions via event bus
76
+ *
77
+ * This is the recommended way for components to request transitions, as it:
78
+ * 1. Works from anywhere in the component tree
79
+ * 2. Gracefully falls back to direct execution if no overlay is available
80
+ * 3. Supports state changes via the standardized event format
81
+ *
82
+ * @param orchestrator - The EventOrchestrator instance
83
+ * @param callback - Function to execute during the transition (while overlay is opaque)
84
+ * @param config - Optional per-request config overrides
85
+ * @returns Promise that resolves after the transition completes
86
+ */
87
+ export declare function transitionWithOverlay(orchestrator: EventOrchestrator, callback: () => void | Promise<void>, config?: Partial<TransitionOverlayConfig>): Promise<void>;
88
+ /**
89
+ * Helper to convert state changes array to callback function
90
+ */
91
+ export declare function stateChangesToCallback(stateChanges: Array<{
92
+ key: string;
93
+ value: any;
94
+ }>): () => void;
95
+ export {};
96
+ //# sourceMappingURL=transitionOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transitionOverlay.d.ts","sourceRoot":"","sources":["../../src/transitionOverlay.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAM/C,MAAM,WAAW,uBAAuB;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IAClD,gBAAgB,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AASD,KAAK,eAAe,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,CAAC;AAEhE;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAoC;IAClD,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,YAAY,CAA2B;IAC/C,OAAO,CAAC,eAAe,CAAyC;IAChE,OAAO,CAAC,cAAc,CAAiC;IACvD,OAAO,CAAC,uBAAuB,CAA8B;gBAEjD,MAAM,EAAE,uBAAuB,EAAE,UAAU,EAAE,UAAU;IAYnE,OAAO,CAAC,oBAAoB;IA8B5B;;;;;;OAMG;IACU,iBAAiB,CAC5B,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EACpC,eAAe,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GACjD,OAAO,CAAC,IAAI,CAAC;IAiBhB,OAAO,CAAC,uBAAuB;YAwBjB,iBAAiB;IAmC/B,OAAO,CAAC,MAAM;YAoDA,gBAAgB;IAsB9B,OAAO,CAAC,OAAO;IAmDf,OAAO,CAAC,qBAAqB;IAW7B;;OAEG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,uBAAuB,CAAC,GAAG,IAAI;IAgBnE;;OAEG;IACI,QAAQ,IAAI,eAAe;IAIlC;;OAEG;IACI,eAAe,IAAI,OAAO;IAIjC;;OAEG;IACI,OAAO,IAAI,IAAI;CAUvB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CACzC,YAAY,EAAE,iBAAiB,EAC/B,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,EACpC,MAAM,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,GACxC,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,GAAG,CAAA;CAAE,CAAC,GAC/C,MAAM,IAAI,CAMZ"}
@@ -0,0 +1,328 @@
1
+ import { setGlobalState } from "./stateManager";
2
+ import { logger } from "./logger";
3
+ const log = logger;
4
+ /**
5
+ * TransitionOverlay - Manages visual overlay transitions for seamless content updates
6
+ *
7
+ * This class provides a fade-to-opaque overlay that hides content changes during state updates.
8
+ *
9
+ * **Concurrency Strategy:**
10
+ * - If a transition is in the **fade-in or hold phase**, incoming requests queue their callbacks
11
+ * to be batched into the current cycle's hold phase
12
+ * - If a transition is in the **fade-out phase**, incoming requests start a new transition cycle
13
+ * after the current one completes
14
+ *
15
+ * This ensures smooth transitions without jarring interruptions or visible content changes.
16
+ */
17
+ export class TransitionOverlay {
18
+ config;
19
+ shadowRoot;
20
+ overlayElement = null;
21
+ currentPhase = "idle";
22
+ queuedCallbacks = [];
23
+ queuedRequests = [];
24
+ activeTransitionPromise = null;
25
+ constructor(config, shadowRoot) {
26
+ this.config = {
27
+ backgroundColor: config.backgroundColor ?? "#000",
28
+ fadeInDuration: config.fadeInDuration ?? 200,
29
+ holdDuration: config.holdDuration ?? 100,
30
+ fadeOutDuration: config.fadeOutDuration ?? 200,
31
+ zIndex: config.zIndex ?? 100,
32
+ };
33
+ this.shadowRoot = shadowRoot;
34
+ this.injectOverlayElement();
35
+ }
36
+ injectOverlayElement() {
37
+ this.overlayElement = document.createElement("div");
38
+ this.overlayElement.className = "transition-overlay";
39
+ this.overlayElement.style.cssText = `
40
+ position: absolute;
41
+ inset: 0;
42
+ background-color: ${this.config.backgroundColor};
43
+ opacity: 0;
44
+ pointer-events: none;
45
+ z-index: ${this.config.zIndex};
46
+ will-change: opacity;
47
+ transition: opacity ${this.config.fadeInDuration}ms ease-in-out;
48
+ `;
49
+ // Append to the shadow root or to .page if it exists
50
+ const pageElement = this.shadowRoot.querySelector(".page");
51
+ const container = pageElement || this.shadowRoot;
52
+ // Ensure the container has relative positioning for absolute overlay
53
+ if (container instanceof HTMLElement) {
54
+ const currentPosition = window.getComputedStyle(container).position;
55
+ if (currentPosition === "static") {
56
+ container.style.position = "relative";
57
+ }
58
+ }
59
+ container.appendChild(this.overlayElement);
60
+ log.trace("TransitionOverlay element injected into shadow DOM");
61
+ }
62
+ /**
63
+ * Execute a transition with the overlay lifecycle
64
+ *
65
+ * @param callback - Function to execute while overlay is opaque (state changes happen here)
66
+ * @param configOverrides - Optional per-request config overrides
67
+ * @returns Promise that resolves after the full transition completes
68
+ */
69
+ async executeTransition(callback, configOverrides) {
70
+ // Merge config overrides
71
+ const effectiveConfig = {
72
+ ...this.config,
73
+ ...configOverrides,
74
+ };
75
+ // Handle concurrency
76
+ if (this.currentPhase !== "idle") {
77
+ return this.handleConcurrentRequest(callback, effectiveConfig);
78
+ }
79
+ // Start new transition
80
+ this.activeTransitionPromise = this.performTransition(callback, effectiveConfig);
81
+ return this.activeTransitionPromise;
82
+ }
83
+ handleConcurrentRequest(callback, config) {
84
+ return new Promise((resolve, reject) => {
85
+ // If we're in fade-in or hold, batch this callback into the current cycle
86
+ if (this.currentPhase === "fade-in" || this.currentPhase === "hold") {
87
+ log.trace("Batching callback into current transition cycle", {
88
+ currentPhase: this.currentPhase
89
+ });
90
+ this.queuedCallbacks.push(callback);
91
+ // Resolve when the current transition completes
92
+ this.activeTransitionPromise?.then(resolve).catch(reject);
93
+ }
94
+ // If we're in fade-out, queue for the next cycle
95
+ else if (this.currentPhase === "fade-out") {
96
+ log.trace("Queueing request for next transition cycle", {
97
+ currentPhase: this.currentPhase
98
+ });
99
+ this.queuedRequests.push({ callback, config, resolve, reject });
100
+ }
101
+ });
102
+ }
103
+ async performTransition(callback, config) {
104
+ if (!this.overlayElement) {
105
+ throw new Error("Overlay element not initialized");
106
+ }
107
+ try {
108
+ // Phase 1: Fade in
109
+ this.currentPhase = "fade-in";
110
+ await this.fadeIn(config.fadeInDuration);
111
+ // Phase 2: Hold & execute callbacks
112
+ this.currentPhase = "hold";
113
+ await this.executeCallbacks(callback, config.holdDuration);
114
+ // Phase 3: Fade out
115
+ this.currentPhase = "fade-out";
116
+ await this.fadeOut(config.fadeOutDuration);
117
+ // Back to idle
118
+ this.currentPhase = "idle";
119
+ // Process any queued requests
120
+ this.processQueuedRequests();
121
+ }
122
+ catch (error) {
123
+ log.error("Transition error:", error);
124
+ this.currentPhase = "idle";
125
+ this.queuedCallbacks = [];
126
+ throw error;
127
+ }
128
+ }
129
+ fadeIn(duration) {
130
+ if (!this.overlayElement)
131
+ return Promise.resolve();
132
+ return new Promise((resolve) => {
133
+ const element = this.overlayElement;
134
+ // Update transition duration
135
+ element.style.transition = `opacity ${duration}ms ease-in-out`;
136
+ // Enable pointer events to block interaction
137
+ element.style.pointerEvents = "all";
138
+ let transitionEndFired = false;
139
+ let fallbackTimerId = null;
140
+ const cleanup = () => {
141
+ if (transitionEndFired)
142
+ return;
143
+ transitionEndFired = true;
144
+ element.removeEventListener("transitionend", transitionEndHandler);
145
+ if (fallbackTimerId !== null) {
146
+ clearTimeout(fallbackTimerId);
147
+ fallbackTimerId = null;
148
+ }
149
+ log.trace("Overlay fade-in complete");
150
+ resolve();
151
+ };
152
+ const transitionEndHandler = (e) => {
153
+ // Only respond to opacity transitions on this element
154
+ if (e.target === element && e.propertyName === "opacity") {
155
+ cleanup();
156
+ }
157
+ };
158
+ element.addEventListener("transitionend", transitionEndHandler);
159
+ // Trigger fade-in by setting opacity to 1
160
+ // Use requestAnimationFrame to ensure CSS transition is applied
161
+ requestAnimationFrame(() => {
162
+ element.style.opacity = "1";
163
+ });
164
+ // Fallback timeout
165
+ fallbackTimerId = window.setTimeout(() => {
166
+ log.trace("Overlay fade-in fallback timeout triggered");
167
+ cleanup();
168
+ }, duration + 50);
169
+ });
170
+ }
171
+ async executeCallbacks(callback, holdDuration) {
172
+ // Execute the main callback
173
+ await Promise.resolve(callback());
174
+ // Execute any batched callbacks
175
+ if (this.queuedCallbacks.length > 0) {
176
+ log.trace(`Executing ${this.queuedCallbacks.length} batched callbacks`);
177
+ for (const queuedCallback of this.queuedCallbacks) {
178
+ await Promise.resolve(queuedCallback());
179
+ }
180
+ this.queuedCallbacks = [];
181
+ }
182
+ // Hold duration
183
+ if (holdDuration > 0) {
184
+ await new Promise(resolve => setTimeout(resolve, holdDuration));
185
+ }
186
+ }
187
+ fadeOut(duration) {
188
+ if (!this.overlayElement)
189
+ return Promise.resolve();
190
+ return new Promise((resolve) => {
191
+ const element = this.overlayElement;
192
+ // Update transition duration
193
+ element.style.transition = `opacity ${duration}ms ease-in-out`;
194
+ let transitionEndFired = false;
195
+ let fallbackTimerId = null;
196
+ const cleanup = () => {
197
+ if (transitionEndFired)
198
+ return;
199
+ transitionEndFired = true;
200
+ element.removeEventListener("transitionend", transitionEndHandler);
201
+ if (fallbackTimerId !== null) {
202
+ clearTimeout(fallbackTimerId);
203
+ fallbackTimerId = null;
204
+ }
205
+ // Disable pointer events after fade-out
206
+ element.style.pointerEvents = "none";
207
+ log.trace("Overlay fade-out complete");
208
+ resolve();
209
+ };
210
+ const transitionEndHandler = (e) => {
211
+ // Only respond to opacity transitions on this element
212
+ if (e.target === element && e.propertyName === "opacity") {
213
+ cleanup();
214
+ }
215
+ };
216
+ element.addEventListener("transitionend", transitionEndHandler);
217
+ // Trigger fade-out by setting opacity to 0
218
+ requestAnimationFrame(() => {
219
+ element.style.opacity = "0";
220
+ });
221
+ // Fallback timeout
222
+ fallbackTimerId = window.setTimeout(() => {
223
+ log.trace("Overlay fade-out fallback timeout triggered");
224
+ cleanup();
225
+ }, duration + 50);
226
+ });
227
+ }
228
+ processQueuedRequests() {
229
+ if (this.queuedRequests.length > 0) {
230
+ log.trace(`Processing ${this.queuedRequests.length} queued transition requests`);
231
+ const request = this.queuedRequests.shift();
232
+ this.performTransition(request.callback, request.config)
233
+ .then(request.resolve)
234
+ .catch(request.reject);
235
+ }
236
+ }
237
+ /**
238
+ * Update the overlay configuration
239
+ */
240
+ updateConfig(config) {
241
+ this.config = {
242
+ ...this.config,
243
+ ...config,
244
+ };
245
+ if (this.overlayElement) {
246
+ if (config.backgroundColor) {
247
+ this.overlayElement.style.backgroundColor = config.backgroundColor;
248
+ }
249
+ if (config.zIndex !== undefined) {
250
+ this.overlayElement.style.zIndex = String(config.zIndex);
251
+ }
252
+ }
253
+ }
254
+ /**
255
+ * Get the current transition phase
256
+ */
257
+ getPhase() {
258
+ return this.currentPhase;
259
+ }
260
+ /**
261
+ * Check if a transition is currently active
262
+ */
263
+ isTransitioning() {
264
+ return this.currentPhase !== "idle";
265
+ }
266
+ /**
267
+ * Clean up the overlay element and resources
268
+ */
269
+ destroy() {
270
+ if (this.overlayElement && this.overlayElement.parentNode) {
271
+ this.overlayElement.parentNode.removeChild(this.overlayElement);
272
+ }
273
+ this.overlayElement = null;
274
+ this.queuedCallbacks = [];
275
+ this.queuedRequests = [];
276
+ this.currentPhase = "idle";
277
+ log.trace("TransitionOverlay destroyed");
278
+ }
279
+ }
280
+ /**
281
+ * Standalone utility for requesting overlay transitions via event bus
282
+ *
283
+ * This is the recommended way for components to request transitions, as it:
284
+ * 1. Works from anywhere in the component tree
285
+ * 2. Gracefully falls back to direct execution if no overlay is available
286
+ * 3. Supports state changes via the standardized event format
287
+ *
288
+ * @param orchestrator - The EventOrchestrator instance
289
+ * @param callback - Function to execute during the transition (while overlay is opaque)
290
+ * @param config - Optional per-request config overrides
291
+ * @returns Promise that resolves after the transition completes
292
+ */
293
+ export async function transitionWithOverlay(orchestrator, callback, config) {
294
+ const transitionBus = orchestrator.getEventBus("page-transition-overlay");
295
+ if (transitionBus) {
296
+ // Wrap in a promise that resolves when the transition completes
297
+ return new Promise((resolve, reject) => {
298
+ try {
299
+ transitionBus.emit("request-transition", {
300
+ callback,
301
+ ...config,
302
+ _resolve: resolve,
303
+ _reject: reject,
304
+ });
305
+ }
306
+ catch (error) {
307
+ // If the emit fails (no listeners), fall back to direct execution
308
+ log.warn("No transition overlay available, executing callback directly");
309
+ Promise.resolve(callback()).then(resolve).catch(reject);
310
+ }
311
+ });
312
+ }
313
+ else {
314
+ // Fallback: no overlay available, execute directly
315
+ log.trace("No transition overlay bus found, executing callback directly");
316
+ await Promise.resolve(callback());
317
+ }
318
+ }
319
+ /**
320
+ * Helper to convert state changes array to callback function
321
+ */
322
+ export function stateChangesToCallback(stateChanges) {
323
+ return () => {
324
+ stateChanges.forEach(({ key, value }) => {
325
+ setGlobalState(key, value);
326
+ });
327
+ };
328
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hawsen-the-first/interactiv",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "A TypeScript framework for building interactive applications with event management, state management, navigation, and screensaver functionality",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",