@geometra/mcp 1.26.0 → 1.27.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.js CHANGED
@@ -8,7 +8,7 @@ function cleanupActiveSession() {
8
8
  return;
9
9
  cleanedUp = true;
10
10
  try {
11
- disconnect();
11
+ disconnect({ closeProxy: true });
12
12
  }
13
13
  catch {
14
14
  /* ignore */
package/dist/session.js CHANGED
@@ -8,6 +8,9 @@ let nextSessionId = 0;
8
8
  function generateSessionId() { return `s${++nextSessionId}`; }
9
9
  let reusableProxies = [];
10
10
  const REUSABLE_PROXY_POOL_LIMIT = 6;
11
+ /** Close idle reusable proxies after 5 minutes of inactivity. */
12
+ const REUSABLE_PROXY_IDLE_TTL_MS = 5 * 60 * 1000;
13
+ let idleProxyTimer = null;
11
14
  const trackedReusableProxyChildren = new WeakSet();
12
15
  const ACTION_UPDATE_TIMEOUT_MS = 2000;
13
16
  const LISTBOX_UPDATE_TIMEOUT_MS = 4500;
@@ -66,9 +69,11 @@ function closeReusableProxy(entry) {
66
69
  catch {
67
70
  /* ignore */
68
71
  }
72
+ ensureIdleProxyTimer();
69
73
  return;
70
74
  }
71
75
  void entry.runtime?.close().catch(() => { });
76
+ ensureIdleProxyTimer();
72
77
  }
73
78
  function closeReusableProxies() {
74
79
  clearReusableProxiesIfExited();
@@ -87,6 +92,25 @@ function closeReusableProxies() {
87
92
  void entry.runtime?.close().catch(() => { });
88
93
  }
89
94
  }
95
+ function evictIdleReusableProxies() {
96
+ clearReusableProxiesIfExited();
97
+ const now = Date.now();
98
+ const stale = reusableProxies.filter(entry => !reusableProxyEntryIsActive(entry) && (now - entry.lastUsedAt) > REUSABLE_PROXY_IDLE_TTL_MS);
99
+ for (const entry of stale) {
100
+ closeReusableProxy(entry);
101
+ }
102
+ ensureIdleProxyTimer();
103
+ }
104
+ function ensureIdleProxyTimer() {
105
+ if (reusableProxies.length > 0 && !idleProxyTimer) {
106
+ idleProxyTimer = setInterval(evictIdleReusableProxies, 60_000);
107
+ idleProxyTimer.unref();
108
+ }
109
+ else if (reusableProxies.length === 0 && idleProxyTimer) {
110
+ clearInterval(idleProxyTimer);
111
+ idleProxyTimer = null;
112
+ }
113
+ }
90
114
  function enforceReusableProxyPoolLimit() {
91
115
  clearReusableProxiesIfExited();
92
116
  if (reusableProxies.length <= REUSABLE_PROXY_POOL_LIMIT)
@@ -139,6 +163,7 @@ function setReusableProxy(proxy, wsUrl, opts) {
139
163
  child.once('error', clear);
140
164
  }
141
165
  enforceReusableProxyPoolLimit();
166
+ ensureIdleProxyTimer();
142
167
  return;
143
168
  }
144
169
  reusableProxies.push({
@@ -153,6 +178,7 @@ function setReusableProxy(proxy, wsUrl, opts) {
153
178
  lastUsedAt: now,
154
179
  });
155
180
  enforceReusableProxyPoolLimit();
181
+ ensureIdleProxyTimer();
156
182
  }
157
183
  function rememberReusableProxyPageUrl(session) {
158
184
  const entry = reusableProxyEntryForSession(session);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geometra/mcp",
3
- "version": "1.26.0",
3
+ "version": "1.27.0",
4
4
  "description": "MCP server for Geometra — interact with running Geometra apps via the geometry protocol, no browser needed",
5
5
  "license": "MIT",
6
6
  "type": "module",