@pixpilot/chrome-lifecycle 0.2.0 → 0.4.0

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.cjs CHANGED
@@ -1 +1 @@
1
- const e=new Map;let t=!1;function n(){t||(t=!0,chrome.windows.onRemoved.addListener(t=>{let n=e.get(t);n&&(n.forEach(e=>{e()}),e.delete(t))}))}function r(t,r){n();let i=e.get(t);return i||(i=new Set,e.set(t,i)),i.add(r),()=>{let n=e.get(t);n&&(n.delete(r),n.size===0&&e.delete(t))}}const i=new Map,a=new Set;let o=!1;function s(){if(!o)throw Error(`Side panel state manager must be initialized with initSidePanelStateManager() before use.`)}function c(){o||(o=!0,chrome.action.onClicked.addListener(e=>{let t=i.get(e.windowId);t&&t.state===`visible`?t.port&&(i.delete(e.windowId),t.port.postMessage({type:`close-side-panel`})):chrome.sidePanel.open({windowId:e.windowId}).catch(console.error)}),chrome.runtime.onConnect.addListener(e=>{e.name===chrome.runtime.id&&(e.onMessage.addListener(t=>{t.type===`side-panel-state-tracker`&&t.state&&u({port:e,state:t.state,reason:t.reason??`unknown`,windowId:t.windowId,type:t.type})}),e.onDisconnect.addListener(e=>{Array.from(i.entries()).forEach(([t,n])=>{n.port&&n.port===e&&u({port:void 0,state:`hidden`,reason:`port-disconnected`,windowId:t,type:`side-panel-state-tracker`})})}))}))}function l(e){if(e.type!==`side-panel-state-tracker`)return;let t={state:e.state,reason:e.reason,windowId:e.windowId};a.forEach(e=>{try{e(t)}catch(e){console.error(`Error in side panel state listener:`,e)}})}function u(e){let{windowId:t,state:n}=e;if(n===`hidden`){i.delete(t),l(e);return}i.set(t,e),l(e)}function d(e){return s(),i.get(e)?.state}function f(e){return s(),d(e)===`visible`}function p(e){return s(),a.add(e),()=>{a.delete(e)}}exports.getSidePanelStateForWindow=d,exports.initSidePanelStateManager=c,exports.isWindowSidePanelVisible=f,exports.onSidePanelStateChange=p,exports.onWindowClose=r;
1
+ const e=new Map;let t=!1;function n(){t||(t=!0,chrome.windows.onRemoved.addListener(t=>{let n=e.get(t);n&&(n.forEach(e=>{e()}),e.delete(t))}))}function r(t,r){n();let i=e.get(t);return i||(i=new Set,e.set(t,i)),i.add(r),()=>{let n=e.get(t);n&&(n.delete(r),n.size===0&&e.delete(t))}}const i=15e3;let a=!1;function o(){a&&console.warn(`Side panel state tracker already initialized`),a=!0;let e,t,n;return chrome.windows.getCurrent(r=>{if(r.id==null){console.error(`[side-panel-state-tracker] Could not get window ID`);return}e=chrome.runtime.connect({name:chrome.runtime.id});let i=r.id;function a(t){try{e.postMessage({...t,windowId:i,type:`side-panel-state-tracker`,timestamp:Date.now()})}catch(e){console.error(`[side-panel-state-tracker] Failed to send message:`,e)}}t=setInterval(()=>{try{e.postMessage({type:`side-panel-heartbeat`,windowId:i,timestamp:Date.now()})}catch(e){console.error(`[side-panel-state-tracker] Heartbeat failed:`,e),t&&clearInterval(t)}},15e3),n=()=>{a({state:document.hidden?`hidden`:`visible`,reason:`visibility-change`})},document.addEventListener(`visibilitychange`,n),e.onDisconnect.addListener(()=>{console.warn(`[side-panel-state-tracker] Background connection lost`),t&&clearInterval(t)}),e.onMessage.addListener(e=>{e.type===`close-side-panel`&&(t&&clearInterval(t),window.close())}),a({state:document.hidden?`hidden`:`visible`,reason:`document-load`})}),()=>{t&&clearInterval(t),n&&document.removeEventListener(`visibilitychange`,n),e&&e.disconnect(),a=!1}}const s=new Map,c=new Set;let l=!1;function u(){if(!l)throw Error(`Side panel state manager must be initialized with initSidePanelStateManager() before use.`)}function d(){l||(l=!0,chrome.action.onClicked.addListener(e=>{let t=s.get(e.windowId);t&&t.state===`visible`?t.port&&(s.delete(e.windowId),t.port.postMessage({type:`close-side-panel`})):chrome.sidePanel.open({windowId:e.windowId}).catch(console.error)}),chrome.runtime.onConnect.addListener(e=>{e.name===chrome.runtime.id&&(e.onMessage.addListener(t=>{t.type===`side-panel-state-tracker`&&t.state&&p({port:e,state:t.state,reason:t.reason??`unknown`,windowId:t.windowId,type:t.type})}),e.onDisconnect.addListener(e=>{Array.from(s.entries()).forEach(([t,n])=>{n.port&&n.port===e&&p({port:void 0,state:`hidden`,reason:`port-disconnected`,windowId:t,type:`side-panel-state-tracker`})})}))}))}function f(e){if(e.type!==`side-panel-state-tracker`)return;let t={state:e.state,reason:e.reason,windowId:e.windowId};c.forEach(e=>{try{e(t)}catch(e){console.error(`Error in side panel state listener:`,e)}})}function p(e){let{windowId:t,state:n}=e;if(n===`hidden`){s.delete(t),f(e);return}s.set(t,e),f(e)}function m(e){return u(),s.get(e)?.state}function h(e){return u(),m(e)===`visible`}function g(e){return u(),c.add(e),()=>{c.delete(e)}}exports.getSidePanelStateForWindow=m,exports.initSidePanelStateManager=d,exports.initializeSidePanelStateTracker=o,exports.isWindowSidePanelVisible=h,exports.onSidePanelStateChange=g,exports.onWindowClose=r;
package/dist/index.d.cts CHANGED
@@ -17,6 +17,12 @@ type CloseCallback = () => void;
17
17
  */
18
18
  declare function onWindowClose(windowId: number, callback: CloseCallback): () => void;
19
19
  //#endregion
20
+ //#region src/side-panel-state-tracker.d.ts
21
+ /**
22
+ * Should only be called inside a Chrome extension side panel page.
23
+ */
24
+ declare function initializeSidePanelStateTracker(): () => void;
25
+ //#endregion
20
26
  //#region src/types/side-panel.d.ts
21
27
  type SidePanelState = 'visible' | 'hidden';
22
28
  interface BaseSidePanelMessage {
@@ -29,6 +35,10 @@ interface SidePanelStateData extends BaseSidePanelMessage {
29
35
  reason: string;
30
36
  }
31
37
  type SidePanelStateChangeData = Omit<SidePanelStateData, 'timestamp' | 'type'>;
38
+ interface SidePanelClientMessage {
39
+ type: 'close-side-panel';
40
+ }
41
+ type SidePanelTabTypes = 'insights' | 'history' | 'settings';
32
42
  //#endregion
33
43
  //#region src/sidepanel-state-manager.d.ts
34
44
  type SidePanelStateListener = (data: SidePanelStateChangeData) => void;
@@ -51,4 +61,4 @@ declare function isWindowSidePanelVisible(windowId: number): boolean;
51
61
  */
52
62
  declare function onSidePanelStateChange(listener: SidePanelStateListener): () => void;
53
63
  //#endregion
54
- export { getSidePanelStateForWindow, initSidePanelStateManager, isWindowSidePanelVisible, onSidePanelStateChange, onWindowClose };
64
+ export { SidePanelClientMessage, SidePanelState, SidePanelStateChangeData, SidePanelStateData, SidePanelTabTypes, getSidePanelStateForWindow, initSidePanelStateManager, initializeSidePanelStateTracker, isWindowSidePanelVisible, onSidePanelStateChange, onWindowClose };
package/dist/index.d.ts CHANGED
@@ -17,6 +17,12 @@ type CloseCallback = () => void;
17
17
  */
18
18
  declare function onWindowClose(windowId: number, callback: CloseCallback): () => void;
19
19
  //#endregion
20
+ //#region src/side-panel-state-tracker.d.ts
21
+ /**
22
+ * Should only be called inside a Chrome extension side panel page.
23
+ */
24
+ declare function initializeSidePanelStateTracker(): () => void;
25
+ //#endregion
20
26
  //#region src/types/side-panel.d.ts
21
27
  type SidePanelState = 'visible' | 'hidden';
22
28
  interface BaseSidePanelMessage {
@@ -29,6 +35,10 @@ interface SidePanelStateData extends BaseSidePanelMessage {
29
35
  reason: string;
30
36
  }
31
37
  type SidePanelStateChangeData = Omit<SidePanelStateData, 'timestamp' | 'type'>;
38
+ interface SidePanelClientMessage {
39
+ type: 'close-side-panel';
40
+ }
41
+ type SidePanelTabTypes = 'insights' | 'history' | 'settings';
32
42
  //#endregion
33
43
  //#region src/sidepanel-state-manager.d.ts
34
44
  type SidePanelStateListener = (data: SidePanelStateChangeData) => void;
@@ -51,4 +61,4 @@ declare function isWindowSidePanelVisible(windowId: number): boolean;
51
61
  */
52
62
  declare function onSidePanelStateChange(listener: SidePanelStateListener): () => void;
53
63
  //#endregion
54
- export { getSidePanelStateForWindow, initSidePanelStateManager, isWindowSidePanelVisible, onSidePanelStateChange, onWindowClose };
64
+ export { SidePanelClientMessage, SidePanelState, SidePanelStateChangeData, SidePanelStateData, SidePanelTabTypes, getSidePanelStateForWindow, initSidePanelStateManager, initializeSidePanelStateTracker, isWindowSidePanelVisible, onSidePanelStateChange, onWindowClose };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- const e=new Map;let t=!1;function n(){t||(t=!0,chrome.windows.onRemoved.addListener(t=>{let n=e.get(t);n&&(n.forEach(e=>{e()}),e.delete(t))}))}function r(t,r){n();let i=e.get(t);return i||(i=new Set,e.set(t,i)),i.add(r),()=>{let n=e.get(t);n&&(n.delete(r),n.size===0&&e.delete(t))}}const i=new Map,a=new Set;let o=!1;function s(){if(!o)throw Error(`Side panel state manager must be initialized with initSidePanelStateManager() before use.`)}function c(){o||(o=!0,chrome.action.onClicked.addListener(e=>{let t=i.get(e.windowId);t&&t.state===`visible`?t.port&&(i.delete(e.windowId),t.port.postMessage({type:`close-side-panel`})):chrome.sidePanel.open({windowId:e.windowId}).catch(console.error)}),chrome.runtime.onConnect.addListener(e=>{e.name===chrome.runtime.id&&(e.onMessage.addListener(t=>{t.type===`side-panel-state-tracker`&&t.state&&u({port:e,state:t.state,reason:t.reason??`unknown`,windowId:t.windowId,type:t.type})}),e.onDisconnect.addListener(e=>{Array.from(i.entries()).forEach(([t,n])=>{n.port&&n.port===e&&u({port:void 0,state:`hidden`,reason:`port-disconnected`,windowId:t,type:`side-panel-state-tracker`})})}))}))}function l(e){if(e.type!==`side-panel-state-tracker`)return;let t={state:e.state,reason:e.reason,windowId:e.windowId};a.forEach(e=>{try{e(t)}catch(e){console.error(`Error in side panel state listener:`,e)}})}function u(e){let{windowId:t,state:n}=e;if(n===`hidden`){i.delete(t),l(e);return}i.set(t,e),l(e)}function d(e){return s(),i.get(e)?.state}function f(e){return s(),d(e)===`visible`}function p(e){return s(),a.add(e),()=>{a.delete(e)}}export{d as getSidePanelStateForWindow,c as initSidePanelStateManager,f as isWindowSidePanelVisible,p as onSidePanelStateChange,r as onWindowClose};
1
+ const e=new Map;let t=!1;function n(){t||(t=!0,chrome.windows.onRemoved.addListener(t=>{let n=e.get(t);n&&(n.forEach(e=>{e()}),e.delete(t))}))}function r(t,r){n();let i=e.get(t);return i||(i=new Set,e.set(t,i)),i.add(r),()=>{let n=e.get(t);n&&(n.delete(r),n.size===0&&e.delete(t))}}let i=!1;function a(){i&&console.warn(`Side panel state tracker already initialized`),i=!0;let e,t,n;return chrome.windows.getCurrent(r=>{if(r.id==null){console.error(`[side-panel-state-tracker] Could not get window ID`);return}e=chrome.runtime.connect({name:chrome.runtime.id});let i=r.id;function a(t){try{e.postMessage({...t,windowId:i,type:`side-panel-state-tracker`,timestamp:Date.now()})}catch(e){console.error(`[side-panel-state-tracker] Failed to send message:`,e)}}t=setInterval(()=>{try{e.postMessage({type:`side-panel-heartbeat`,windowId:i,timestamp:Date.now()})}catch(e){console.error(`[side-panel-state-tracker] Heartbeat failed:`,e),t&&clearInterval(t)}},15e3),n=()=>{a({state:document.hidden?`hidden`:`visible`,reason:`visibility-change`})},document.addEventListener(`visibilitychange`,n),e.onDisconnect.addListener(()=>{console.warn(`[side-panel-state-tracker] Background connection lost`),t&&clearInterval(t)}),e.onMessage.addListener(e=>{e.type===`close-side-panel`&&(t&&clearInterval(t),window.close())}),a({state:document.hidden?`hidden`:`visible`,reason:`document-load`})}),()=>{t&&clearInterval(t),n&&document.removeEventListener(`visibilitychange`,n),e&&e.disconnect(),i=!1}}const o=new Map,s=new Set;let c=!1;function l(){if(!c)throw Error(`Side panel state manager must be initialized with initSidePanelStateManager() before use.`)}function u(){c||(c=!0,chrome.action.onClicked.addListener(e=>{let t=o.get(e.windowId);t&&t.state===`visible`?t.port&&(o.delete(e.windowId),t.port.postMessage({type:`close-side-panel`})):chrome.sidePanel.open({windowId:e.windowId}).catch(console.error)}),chrome.runtime.onConnect.addListener(e=>{e.name===chrome.runtime.id&&(e.onMessage.addListener(t=>{t.type===`side-panel-state-tracker`&&t.state&&f({port:e,state:t.state,reason:t.reason??`unknown`,windowId:t.windowId,type:t.type})}),e.onDisconnect.addListener(e=>{Array.from(o.entries()).forEach(([t,n])=>{n.port&&n.port===e&&f({port:void 0,state:`hidden`,reason:`port-disconnected`,windowId:t,type:`side-panel-state-tracker`})})}))}))}function d(e){if(e.type!==`side-panel-state-tracker`)return;let t={state:e.state,reason:e.reason,windowId:e.windowId};s.forEach(e=>{try{e(t)}catch(e){console.error(`Error in side panel state listener:`,e)}})}function f(e){let{windowId:t,state:n}=e;if(n===`hidden`){o.delete(t),d(e);return}o.set(t,e),d(e)}function p(e){return l(),o.get(e)?.state}function m(e){return l(),p(e)===`visible`}function h(e){return l(),s.add(e),()=>{s.delete(e)}}export{p as getSidePanelStateForWindow,u as initSidePanelStateManager,a as initializeSidePanelStateTracker,m as isWindowSidePanelVisible,h as onSidePanelStateChange,r as onWindowClose};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pixpilot/chrome-lifecycle",
3
3
  "type": "module",
4
- "version": "0.2.0",
4
+ "version": "0.4.0",
5
5
  "description": "Lifecycle management utilities for Chrome extensions.",
6
6
  "author": "m.doaie <m.doaie@hotmail.com>",
7
7
  "license": "MIT",
@@ -30,10 +30,10 @@
30
30
  "tsdown": "^0.15.9",
31
31
  "typescript": "^5.9.3",
32
32
  "@internal/eslint-config": "0.3.0",
33
- "@internal/tsdown-config": "0.1.0",
33
+ "@internal/prettier-config": "0.1.0",
34
34
  "@internal/tsconfig": "0.1.0",
35
- "@internal/vitest-config": "0.1.0",
36
- "@internal/prettier-config": "0.1.0"
35
+ "@internal/tsdown-config": "0.1.0",
36
+ "@internal/vitest-config": "0.1.0"
37
37
  },
38
38
  "prettier": "@internal/prettier-config",
39
39
  "scripts": {