js.foresight-devtools 1.3.2 → 1.3.3

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Bart Spaans
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Bart Spaans
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
package/README.md CHANGED
@@ -1,90 +1,90 @@
1
- # js.foresight-devtools
2
-
3
- [![npm version](https://img.shields.io/npm/v/js.foresight-devtools.svg)](https://www.npmjs.com/package/js.foresight-devtools)
4
- [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
-
7
- `ForesightJS` offers dedicated [Development Tools](https://github.com/spaansba/ForesightJS/tree/main/packages/js.foresight-devtools), written in [Lit](https://lit.dev/), to help you better understand and fine-tune how `ForesightJS` works within your application. You can see the development tools in action on the [playground page](https://foresightjs.com/#playground), which includes visual trajectory indicators, element boundaries, and a control panel in the bottom-right corner.
8
-
9
- These tools are built entirely using `ForesightJS`'s [built-in events](/docs/events), demonstrating how you can create your own monitoring and debugging tools using the same event system.
10
-
11
- ## Installation
12
-
13
- To install the `ForesightJS` Development Tools package, use your preferred package manager:
14
-
15
- ```bash
16
- pnpm add -D js.foresight-devtools
17
- # or
18
- npm install -D js.foresight-devtools
19
- # or
20
- yarn add -D js.foresight-devtools
21
- ```
22
-
23
- ## Enabling Development Tools
24
-
25
- ```javascript
26
- import { ForesightManager } from "js.foresight"
27
- import { ForesightDevtools } from "js.foresight-devtools"
28
-
29
- // Initialize ForesightJS
30
- ForesightManager.initialize({})
31
-
32
- // Initialize the development tools (all options are optional)
33
- ForesightDevtools.initialize({
34
- showDebugger: true,
35
- isControlPanelDefaultMinimized: false, // optional setting which allows you to minimize the control panel on default
36
- showNameTags: true, // optional setting which shows the name of the element
37
- sortElementList: "visibility", // optional setting for how the elements in the control panel are sorted
38
- logging: {
39
- logLocation: "controlPanel", // Where to log the Foresight Events
40
- callbackCompleted: true,
41
- elementReactivated: true,
42
- callbackInvoked: true,
43
- elementDataUpdated: false,
44
- elementRegistered: false,
45
- elementUnregistered: false,
46
- managerSettingsChanged: true,
47
- mouseTrajectoryUpdate: false, // dont log this to the devtools
48
- scrollTrajectoryUpdate: false, // dont log this to the devtools
49
- deviceStrategyChanged: true,
50
- },
51
- })
52
- ```
53
-
54
- ## Development Tools Features
55
-
56
- Once enabled, the `ForesightJS` Development Tools add several visual layers to your application, including mouse and scroll trajectories and element hitboxes. A control panel also appears in the bottom-right corner of the screen.
57
-
58
- ### Control Panel
59
-
60
- The control panel provides three main tabs for debugging and configuration. Each tab serves a specific purpose in understanding and tuning ForesightJS behavior.
61
-
62
- #### Settings Tab
63
-
64
- The Settings tab provides real-time controls for all [Global Configurations](/docs/configuration/global-settings). Changes made through these controls immediately affect the `ForesightManager` configuration, allowing you to see how different settings impact your app without fiddling in your code.
65
-
66
- #### Elements Tab
67
-
68
- The Elements tab displays a overview of all currently registered elements within the `ForesightManage`r. Each element entry shows its current status through color-coded indicators:
69
-
70
- - 🟢 **Green** - Active visible elements in desktop mode
71
- - ⚫ **Grey** - Active invisible elements in desktop mode
72
- - 🟣 **Purple** - Active elements while in touch device mode (all elements, we dont track visibility in this mode)
73
- - 🟡 **Yellow** - Elements which callbacks are currently executing
74
- - 🔘 **Light Gray** - Inactive elements
75
-
76
- Each element can also be expanded to reveal its [`ForesightElementData`](/docs/next/getting-started/typescript#foresightelementdata) information including settings, callback status, and metadata. A countdown timer appears for elements in their reactivation cooldown period (`reactivateAfter`), clicking this timer will instantly reactivate the element.
77
-
78
- #### Log Tab
79
-
80
- The Log tab displays real-time [events](/docs/events) emitted by `ForesightJS`. You can see callback execution times, the full element's lifecycle and other system events. Events can be filtered through the devtools initialization configuration or in the control panel itself.
81
-
82
- You can also print out the complete [`ForesightManager.instance.getManagerData`](/docs/debugging/static-properties#foresightmanagerinstancegetmanagerdata) state without having to call it from your code.
83
-
84
- :::caution
85
- Avoid logging frequently emitted events to the browser console, as it can noticeably slow down your development environment. Use the control panel for this instead.
86
- :::
87
-
88
- :::note
89
- Element overlay visualization and visibility sorting in the control panel only work with desktop/mouse prediction strategies. When debugging `touchDeviceStrategy` configurations, these features are not available as touch strategies don't track the same positioning data.
90
- :::
1
+ # js.foresight-devtools
2
+
3
+ [![npm version](https://img.shields.io/npm/v/js.foresight-devtools.svg)](https://www.npmjs.com/package/js.foresight-devtools)
4
+ [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ `ForesightJS` offers dedicated [Development Tools](https://github.com/spaansba/ForesightJS/tree/main/packages/js.foresight-devtools), written in [Lit](https://lit.dev/), to help you better understand and fine-tune how `ForesightJS` works within your application. You can see the development tools in action on the [playground page](https://foresightjs.com/#playground), which includes visual trajectory indicators, element boundaries, and a control panel in the bottom-right corner.
8
+
9
+ These tools are built entirely using `ForesightJS`'s [built-in events](/docs/events), demonstrating how you can create your own monitoring and debugging tools using the same event system.
10
+
11
+ ## Installation
12
+
13
+ To install the `ForesightJS` Development Tools package, use your preferred package manager:
14
+
15
+ ```bash
16
+ pnpm add -D js.foresight-devtools
17
+ # or
18
+ npm install -D js.foresight-devtools
19
+ # or
20
+ yarn add -D js.foresight-devtools
21
+ ```
22
+
23
+ ## Enabling Development Tools
24
+
25
+ ```javascript
26
+ import { ForesightManager } from "js.foresight"
27
+ import { ForesightDevtools } from "js.foresight-devtools"
28
+
29
+ // Initialize ForesightJS
30
+ ForesightManager.initialize({})
31
+
32
+ // Initialize the development tools (all options are optional)
33
+ ForesightDevtools.initialize({
34
+ showDebugger: true,
35
+ isControlPanelDefaultMinimized: false, // optional setting which allows you to minimize the control panel on default
36
+ showNameTags: true, // optional setting which shows the name of the element
37
+ sortElementList: "visibility", // optional setting for how the elements in the control panel are sorted
38
+ logging: {
39
+ logLocation: "controlPanel", // Where to log the Foresight Events
40
+ callbackCompleted: true,
41
+ elementReactivated: true,
42
+ callbackInvoked: true,
43
+ elementDataUpdated: false,
44
+ elementRegistered: false,
45
+ elementUnregistered: false,
46
+ managerSettingsChanged: true,
47
+ mouseTrajectoryUpdate: false, // dont log this to the devtools
48
+ scrollTrajectoryUpdate: false, // dont log this to the devtools
49
+ deviceStrategyChanged: true,
50
+ },
51
+ })
52
+ ```
53
+
54
+ ## Development Tools Features
55
+
56
+ Once enabled, the `ForesightJS` Development Tools add several visual layers to your application, including mouse and scroll trajectories and element hitboxes. A control panel also appears in the bottom-right corner of the screen.
57
+
58
+ ### Control Panel
59
+
60
+ The control panel provides three main tabs for debugging and configuration. Each tab serves a specific purpose in understanding and tuning ForesightJS behavior.
61
+
62
+ #### Settings Tab
63
+
64
+ The Settings tab provides real-time controls for all [Global Configurations](/docs/configuration/global-settings). Changes made through these controls immediately affect the `ForesightManager` configuration, allowing you to see how different settings impact your app without fiddling in your code.
65
+
66
+ #### Elements Tab
67
+
68
+ The Elements tab displays a overview of all currently registered elements within the `ForesightManage`r. Each element entry shows its current status through color-coded indicators:
69
+
70
+ - 🟢 **Green** - Active visible elements in desktop mode
71
+ - ⚫ **Grey** - Active invisible elements in desktop mode
72
+ - 🟣 **Purple** - Active elements while in touch device mode (all elements, we dont track visibility in this mode)
73
+ - 🟡 **Yellow** - Elements which callbacks are currently executing
74
+ - 🔘 **Light Gray** - Inactive elements
75
+
76
+ Each element can also be expanded to reveal its [`ForesightElementData`](/docs/next/getting-started/typescript#foresightelementdata) information including settings, callback status, and metadata. A countdown timer appears for elements in their reactivation cooldown period (`reactivateAfter`), clicking this timer will instantly reactivate the element.
77
+
78
+ #### Log Tab
79
+
80
+ The Log tab displays real-time [events](/docs/events) emitted by `ForesightJS`. You can see callback execution times, the full element's lifecycle and other system events. Events can be filtered through the devtools initialization configuration or in the control panel itself.
81
+
82
+ You can also print out the complete [`ForesightManager.instance.getManagerData`](/docs/debugging/static-properties#foresightmanagerinstancegetmanagerdata) state without having to call it from your code.
83
+
84
+ :::caution
85
+ Avoid logging frequently emitted events to the browser console, as it can noticeably slow down your development environment. Use the control panel for this instead.
86
+ :::
87
+
88
+ :::note
89
+ Element overlay visualization and visibility sorting in the control panel only work with desktop/mouse prediction strategies. When debugging `touchDeviceStrategy` configurations, these features are not available as touch strategies don't track the same positioning data.
90
+ :::
package/dist/index.js CHANGED
@@ -395,7 +395,7 @@ var ze=Object.defineProperty;var He=Object.getOwnPropertyDescriptor;var n=(o,r,e
395
395
  z-index: 5;
396
396
  min-height: 36px;
397
397
  }
398
- `],B=n([tt("tab-header")],B);import{html as rt}from"lit";import{customElement as st,property as Ce}from"lit/decorators.js";import{LitElement as nt,html as ke,css as it}from"lit";import{property as ot,state as at}from"lit/decorators.js";var p=class p extends nt{constructor(){super(...arguments);this.isDropdownOpen=!1;this.dropdownOptions=[];this._toggleDropdown=e=>{e.stopPropagation(),this.isDropdownOpen?this._closeDropdown():(p.currentlyOpen&&p.currentlyOpen!==this&&p.currentlyOpen._closeDropdown(),this.isDropdownOpen=!0,p.currentlyOpen=this,requestAnimationFrame(()=>{this._positionDropdown()}))};this._handleOutsideClick=e=>{this.isDropdownOpen&&(e.composedPath().includes(this)||this._closeDropdown())}}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this._handleOutsideClick)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this._handleOutsideClick),p.currentlyOpen===this&&(p.currentlyOpen=null)}_closeDropdown(){this.isDropdownOpen=!1,p.currentlyOpen===this&&(p.currentlyOpen=null)}_positionDropdown(){if(typeof window>"u")return;let e=this.shadowRoot?.querySelector(".trigger-button"),t=this.shadowRoot?.querySelector(".dropdown-menu");if(e&&t){let i=e.getBoundingClientRect(),a=t.offsetHeight||200,s=i.bottom+5,d=window.innerWidth-i.right;window.innerHeight-i.bottom<a&&i.top>a?t.style.top=`${i.top-a-5}px`:t.style.top=`${s}px`,t.style.right=`${d}px`}}render(){let e=`trigger-button ${this.isDropdownOpen?"active":""}`,t=`dropdown-menu ${this.isDropdownOpen?"active":""}`;return ke`
398
+ `],B=n([tt("tab-header")],B);import{html as rt}from"lit";import{customElement as st,property as Ce}from"lit/decorators.js";import{LitElement as nt,html as ke,css as it}from"lit";import{property as ot,state as at}from"lit/decorators.js";var p=class p extends nt{constructor(){super(...arguments);this.isDropdownOpen=!1;this.dropdownOptions=[];this._toggleDropdown=e=>{e.stopPropagation(),this.isDropdownOpen?this._closeDropdown():(p.currentlyOpen&&p.currentlyOpen!==this&&p.currentlyOpen._closeDropdown(),this.isDropdownOpen=!0,p.currentlyOpen=this,this._positionDropdown())};this._handleOutsideClick=e=>{this.isDropdownOpen&&(e.composedPath().includes(this)||this._closeDropdown())}}connectedCallback(){super.connectedCallback(),document.addEventListener("click",this._handleOutsideClick)}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("click",this._handleOutsideClick),p.currentlyOpen===this&&(p.currentlyOpen=null)}_closeDropdown(){this.isDropdownOpen=!1,p.currentlyOpen===this&&(p.currentlyOpen=null)}_positionDropdown(){if(typeof window>"u")return;let e=this.shadowRoot?.querySelector(".trigger-button"),t=this.shadowRoot?.querySelector(".dropdown-menu");if(e&&t){let i=e.getBoundingClientRect(),a=t.offsetHeight||200,s=i.bottom+5,d=window.innerWidth-i.right;window.innerHeight-i.bottom<a&&i.top>a?t.style.top=`${i.top-a-5}px`:t.style.top=`${s}px`,t.style.right=`${d}px`}}render(){let e=`trigger-button ${this.isDropdownOpen?"active":""}`,t=`dropdown-menu ${this.isDropdownOpen?"active":""}`;return ke`
399
399
  <div class="dropdown-container">
400
400
  <button
401
401
  class="${e}"
@@ -1667,7 +1667,7 @@ Click on the copy icon to easely copy the new setting into your project
1667
1667
  border-bottom: 1px solid rgba(176, 196, 222, 0.2);
1668
1668
  padding-bottom: 8px;
1669
1669
  }
1670
- `,n([T()],m.prototype,"managerSettings",2),n([T()],m.prototype,"initialSettings",2),n([T()],m.prototype,"devtoolsSettings",2),n([T()],m.prototype,"changedSettings",2),n([T()],m.prototype,"currentCorner",2),n([T()],m.prototype,"touchDeviceStrategyOptions",2),n([T()],m.prototype,"minimumConnectionTypeOptions",2),n([T()],m.prototype,"cornerOptions",2),m=n([fn("settings-tab")],m);var w=class extends yn{constructor(){super();this.isMinimized=l.instance.devtoolsSettings.isControlPanelDefaultMinimized;this.isTouchDevice=!1;this.isWarningDismissed=!1;this.corner="bottom-right";this.localStorageSelectedTabKey="foresight-devtools-control-panel-tab";this.localStorageCornerKey="foresight-devtools-control-panel-corner";this._abortController=null;this.activeTab=this.getStoredTab(),this.corner=this.getStoredCorner(),this.isTouchDevice=Ae.instance.getManagerData.currentDeviceStrategy==="touch"}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;Ae.instance.addEventListener("deviceStrategyChanged",t=>{this.isTouchDevice=t.newStrategy==="touch",t.newStrategy==="touch"&&(this.isWarningDismissed=!1)},{signal:e}),this.addEventListener("corner-change",t=>{this.setCorner(t.detail.corner)},{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null}getStoredTab(){try{return localStorage.getItem(this.localStorageSelectedTabKey)||"logs"}catch(e){return console.error(e),"logs"}}getStoredCorner(){try{let e=localStorage.getItem(this.localStorageCornerKey);if(e)return e}catch(e){console.error("ForesightDevtools: Failed to load corner from localStorage:",e)}return"bottom-right"}_handleTabChange(e){this.activeTab=e.detail.tab,this.setStoredTab(this.activeTab)}setStoredTab(e){try{localStorage.setItem(this.localStorageSelectedTabKey,e)}catch(t){console.warn("ForesightDevtools: Failed to save tab preference to localStorage:",t)}}setStoredCorner(e){try{localStorage.setItem(this.localStorageCornerKey,e)}catch(t){console.warn("ForesightDevtools: Failed to save corner to localStorage:",t)}}dismissWarning(){this.isWarningDismissed=!0}setCorner(e){this.corner=e,this.setStoredCorner(this.corner),this.requestUpdate()}handleMinimizeClick(e){e.stopPropagation(),this.isMinimized=!this.isMinimized}getMinimizeSymbol(){return this.isMinimized?"+":"\u2212"}render(){return xn`
1670
+ `,n([T()],m.prototype,"managerSettings",2),n([T()],m.prototype,"initialSettings",2),n([T()],m.prototype,"devtoolsSettings",2),n([T()],m.prototype,"changedSettings",2),n([T()],m.prototype,"currentCorner",2),n([T()],m.prototype,"touchDeviceStrategyOptions",2),n([T()],m.prototype,"minimumConnectionTypeOptions",2),n([T()],m.prototype,"cornerOptions",2),m=n([fn("settings-tab")],m);var w=class extends yn{constructor(){super();this.isMinimized=l.instance.devtoolsSettings.isControlPanelDefaultMinimized;this.isTouchDevice=!1;this.isWarningDismissed=!1;this.corner="bottom-right";this.localStorageSelectedTabKey="foresight-devtools-control-panel-tab";this.localStorageCornerKey="foresight-devtools-control-panel-corner";this._abortController=null;this.activeTab=this.getStoredTab(),this.corner=this.getStoredCorner(),this.isTouchDevice=Ae.instance.getManagerData.currentDeviceStrategy==="touch"}connectedCallback(){super.connectedCallback(),this._abortController=new AbortController;let{signal:e}=this._abortController;Ae.instance.addEventListener("deviceStrategyChanged",t=>{this.isTouchDevice=t.newStrategy==="touch",t.newStrategy==="touch"&&(this.isWarningDismissed=!1)},{signal:e}),this.addEventListener("corner-change",(t=>{this.setCorner(t.detail.corner)}),{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController?.abort(),this._abortController=null}getStoredTab(){try{return localStorage.getItem(this.localStorageSelectedTabKey)||"logs"}catch(e){return console.error(e),"logs"}}getStoredCorner(){try{let e=localStorage.getItem(this.localStorageCornerKey);if(e)return e}catch(e){console.error("ForesightDevtools: Failed to load corner from localStorage:",e)}return"bottom-right"}_handleTabChange(e){this.activeTab=e.detail.tab,this.setStoredTab(this.activeTab)}setStoredTab(e){try{localStorage.setItem(this.localStorageSelectedTabKey,e)}catch(t){console.warn("ForesightDevtools: Failed to save tab preference to localStorage:",t)}}setStoredCorner(e){try{localStorage.setItem(this.localStorageCornerKey,e)}catch(t){console.warn("ForesightDevtools: Failed to save corner to localStorage:",t)}}dismissWarning(){this.isWarningDismissed=!0}setCorner(e){this.corner=e,this.setStoredCorner(this.corner),this.requestUpdate()}handleMinimizeClick(e){e.stopPropagation(),this.isMinimized=!this.isMinimized}getMinimizeSymbol(){return this.isMinimized?"+":"\u2212"}render(){return xn`
1671
1671
  <div class="control-wrapper ${this.corner} ${this.isMinimized?"minimized":""}">
1672
1672
  <div class="title-wrapper">
1673
1673
  <button @click="${this.handleMinimizeClick}" class="minimize-button">
@@ -1940,7 +1940,7 @@ Click on the copy icon to easely copy the new setting into your project
1940
1940
  border-bottom: 4px solid transparent;
1941
1941
  filter: drop-shadow(0 0 6px rgba(59, 130, 246, 0.6));
1942
1942
  }
1943
- `],n([se()],M.prototype,"_mousePredictionIsEnabled",2),n([se()],M.prototype,"_isVisible",2),n([se()],M.prototype,"_trajectoryStyles",2),M=n([_n("mouse-trajectory")],M);import{LitElement as On,html as Pn,css as Un}from"lit";import{customElement as Nn,state as te}from"lit/decorators.js";import{styleMap as An}from"lit/directives/style-map.js";import{ForesightManager as N}from"js.foresight";var C=class extends On{constructor(){super(...arguments);this._abortController=new AbortController;this._scrollPredictionIsEnabled=N.instance.getManagerData.globalSettings.enableScrollPrediction;this._scrollMargin=N.instance.getManagerData.globalSettings.scrollMargin;this._isVisible=!1;this._trajectoryStyles={};this._isUpdateScheduled=!1;this._latestScrollTrajectory=null;this.handleTrajectoryReset=e=>{("wasLastActiveElement"in e&&e.wasLastActiveElement||"wasLastRegisteredElement"in e&&e.wasLastRegisteredElement)&&(this._isVisible=!1,this._trajectoryStyles={transform:"translate(0px, 0px) rotate(0deg)"})};this.handleSettingsChange=e=>{let t=e.managerData.globalSettings.enableScrollPrediction;this._scrollPredictionIsEnabled=t,t||(this._isVisible=!1);let i=e.updatedSettings.find(a=>a.setting==="scrollMargin");i&&(this._scrollMargin=i.newValue)};this.handleScrollUpdate=e=>{this._scrollPredictionIsEnabled&&(this._isVisible=!0,this._latestScrollTrajectory={currentPoint:e.currentPoint,predictedPoint:e.predictedPoint},this._isUpdateScheduled||(this._isUpdateScheduled=!0,requestAnimationFrame(this.renderScrollTrajectory)))};this.renderScrollTrajectory=()=>{if(!this._latestScrollTrajectory){this._isUpdateScheduled=!1;return}let{currentPoint:e,predictedPoint:t}=this._latestScrollTrajectory,i=t.x-e.x,a=t.y-e.y,s=Math.atan2(a,i)*180/Math.PI;this._trajectoryStyles={transform:`translate(${e.x}px, ${e.y}px) rotate(${s}deg)`},this._isUpdateScheduled=!1,this.requestUpdate()}}connectedCallback(){super.connectedCallback();let{signal:e}=this._abortController;N.instance.addEventListener("scrollTrajectoryUpdate",this.handleScrollUpdate,{signal:e}),N.instance.addEventListener("mouseTrajectoryUpdate",()=>{this._isVisible=!1},{signal:e}),N.instance.addEventListener("callbackCompleted",this.handleTrajectoryReset,{signal:e}),N.instance.addEventListener("elementUnregistered",this.handleTrajectoryReset,{signal:e}),N.instance.addEventListener("managerSettingsChanged",this.handleSettingsChange,{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController.abort()}render(){let e={display:this._isVisible?"block":"none",width:`${this._scrollMargin}px`,...this._trajectoryStyles};return Pn` <div class="scroll-trajectory-line" style=${An(e)}></div> `}};C.styles=[Un`
1943
+ `],n([se()],M.prototype,"_mousePredictionIsEnabled",2),n([se()],M.prototype,"_isVisible",2),n([se()],M.prototype,"_trajectoryStyles",2),M=n([_n("mouse-trajectory")],M);import{LitElement as On,html as Pn,css as Un}from"lit";import{customElement as Nn,state as te}from"lit/decorators.js";import{styleMap as An}from"lit/directives/style-map.js";import{ForesightManager as N}from"js.foresight";var C=class extends On{constructor(){super(...arguments);this._abortController=new AbortController;this._scrollPredictionIsEnabled=N.instance.getManagerData.globalSettings.enableScrollPrediction;this._scrollMargin=N.instance.getManagerData.globalSettings.scrollMargin;this._isVisible=!1;this._trajectoryStyles={};this._isUpdateScheduled=!1;this._latestScrollTrajectory=null;this.handleTrajectoryReset=e=>{("wasLastActiveElement"in e&&e.wasLastActiveElement||"wasLastRegisteredElement"in e&&e.wasLastRegisteredElement)&&(this._isVisible=!1,this._trajectoryStyles={transform:"translate(0px, 0px) rotate(0deg)"})};this.handleSettingsChange=e=>{let t=e.managerData.globalSettings.enableScrollPrediction;this._scrollPredictionIsEnabled=t,t||(this._isVisible=!1);let i=e.updatedSettings.find(a=>a.setting==="scrollMargin");i&&(this._scrollMargin=i.newValue)};this.handleScrollUpdate=e=>{this._scrollPredictionIsEnabled&&(this._isVisible=!0,this._latestScrollTrajectory={currentPoint:e.currentPoint,predictedPoint:e.predictedPoint},this._isUpdateScheduled||(this._isUpdateScheduled=!0,this.renderScrollTrajectory()))};this.renderScrollTrajectory=()=>{if(!this._latestScrollTrajectory){this._isUpdateScheduled=!1;return}let{currentPoint:e,predictedPoint:t}=this._latestScrollTrajectory,i=t.x-e.x,a=t.y-e.y,s=Math.atan2(a,i)*180/Math.PI;this._trajectoryStyles={transform:`translate(${e.x}px, ${e.y}px) rotate(${s}deg)`},this._isUpdateScheduled=!1,this.requestUpdate()}}connectedCallback(){super.connectedCallback();let{signal:e}=this._abortController;N.instance.addEventListener("scrollTrajectoryUpdate",this.handleScrollUpdate,{signal:e}),N.instance.addEventListener("mouseTrajectoryUpdate",()=>{this._isVisible=!1},{signal:e}),N.instance.addEventListener("callbackCompleted",this.handleTrajectoryReset,{signal:e}),N.instance.addEventListener("elementUnregistered",this.handleTrajectoryReset,{signal:e}),N.instance.addEventListener("managerSettingsChanged",this.handleSettingsChange,{signal:e})}disconnectedCallback(){super.disconnectedCallback(),this._abortController.abort()}render(){let e={display:this._isVisible?"block":"none",width:`${this._scrollMargin}px`,...this._trajectoryStyles};return Pn` <div class="scroll-trajectory-line" style=${An(e)}></div> `}};C.styles=[Un`
1944
1944
  :host {
1945
1945
  display: block;
1946
1946
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js.foresight-devtools",
3
- "version": "1.3.2",
3
+ "version": "1.3.3",
4
4
  "description": "Visual debugging tools for ForesightJS - mouse trajectory prediction and element interaction visualization",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -40,12 +40,12 @@
40
40
  "js.foresight": "^3.3.2"
41
41
  },
42
42
  "devDependencies": {
43
- "@types/node": "^24.3.0",
43
+ "@types/node": "^24.10.1",
44
44
  "tslib": "^2.8.1",
45
- "tsup": "^8.5.0",
46
- "typescript": "^5.9.2",
47
- "vitest": "^3.2.4",
48
- "js.foresight": "3.3.2"
45
+ "tsup": "^8.5.1",
46
+ "typescript": "^5.9.3",
47
+ "vitest": "^4.0.9",
48
+ "js.foresight": "3.3.3"
49
49
  },
50
50
  "dependencies": {
51
51
  "@thednp/position-observer": "^1.1.0",