@hoox-sh/hoox-shared 1.2.0 → 1.3.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.
@@ -1 +1 @@
1
- {"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../../src/stores/config-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiBH,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAoF3E,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,UAAU,EAAE,SAAS,CAAC;IACtB,aAAa,EAAE,uBAAuB,CAAC;IACvC,YAAY,EAAE,OAAO,CAAC;CACvB;AAID,UAAU,aAAa;IACrB,+DAA+D;IAC/D,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACtD,8CAA8C;IAC9C,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,yCAAyC;IACzC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,8CAA8C;IAC9C,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,uBAAuB,KAAK,IAAI,CAAC;CACtE;AAiBD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;eAtClB,MAAM,GAAG,OAAO;2BACJ,MAAM;qBACZ,MAAM;;;;;;;;;;;;;;;;sBAKL,OAAO;sBAOP,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI;uBAEtC,MAAM,IAAI;qBAEZ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI;4BAE9B,CAAC,OAAO,EAAE,MAAM,uBAAuB,KAAK,IAAI;;;eApB7D,MAAM,GAAG,OAAO;2BACJ,MAAM;qBACZ,MAAM;;;;;;;;;;;;;;;;sBAKL,OAAO;sBAOP,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI;uBAEtC,MAAM,IAAI;qBAEZ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI;4BAE9B,CAAC,OAAO,EAAE,MAAM,uBAAuB,KAAK,IAAI;;EA+ErE,CAAC"}
1
+ {"version":3,"file":"config-store.d.ts","sourceRoot":"","sources":["../../src/stores/config-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmBH,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAM3E,qFAAqF;AACrF,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AA0ID,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,UAAU,EAAE,SAAS,CAAC;IACtB,aAAa,EAAE,uBAAuB,CAAC;IACvC,YAAY,EAAE,OAAO,CAAC;CACvB;AAID,UAAU,aAAa;IACrB,+DAA+D;IAC/D,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACtD,8CAA8C;IAC9C,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,yCAAyC;IACzC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,8CAA8C;IAC9C,kBAAkB,EAAE,CAAC,OAAO,EAAE,MAAM,uBAAuB,KAAK,IAAI,CAAC;CACtE;AAiBD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;eAtClB,MAAM,GAAG,OAAO;2BACJ,MAAM;qBACZ,MAAM;;;;;;;;;;;;;;;;sBAKL,OAAO;sBAOP,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI;uBAEtC,MAAM,IAAI;qBAEZ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI;4BAE9B,CAAC,OAAO,EAAE,MAAM,uBAAuB,KAAK,IAAI;;;eApB7D,MAAM,GAAG,OAAO;2BACJ,MAAM;qBACZ,MAAM;;;;;;;;;;;;;;;;sBAKL,OAAO;sBAOP,CAAC,OAAO,EAAE,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI;uBAEtC,MAAM,IAAI;qBAEZ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI;4BAE9B,CAAC,OAAO,EAAE,MAAM,uBAAuB,KAAK,IAAI;;EA+ErE,CAAC"}
@@ -131,37 +131,287 @@ function validateConfig(config) {
131
131
  return errors;
132
132
  }
133
133
 
134
+ // src/path-utils.ts
135
+ import {
136
+ existsSync as existsSync2,
137
+ mkdirSync as mkdirSync2,
138
+ readFileSync as readFileSync2,
139
+ writeFileSync as writeFileSync2,
140
+ chmodSync as chmodSync2
141
+ } from "fs";
142
+ import { homedir as homedir2 } from "os";
143
+ import { dirname, join as join2, resolve } from "path";
144
+ function createHooxPath(path) {
145
+ return path;
146
+ }
147
+ function getHooxHome() {
148
+ try {
149
+ const override = process.env.HOOX_HOME?.trim();
150
+ if (override) {
151
+ return createHooxPath(resolve(override));
152
+ }
153
+ const home = homedir2();
154
+ if (!home || home.length === 0) {
155
+ return createHooxPath(resolve(process.cwd(), ".hoox"));
156
+ }
157
+ return createHooxPath(join2(home, ".hoox"));
158
+ } catch {
159
+ return createHooxPath(resolve(process.cwd(), ".hoox"));
160
+ }
161
+ }
162
+ function isHooxSetupRoot(dir) {
163
+ if (!dir)
164
+ return false;
165
+ try {
166
+ const root = resolve(dir);
167
+ if (!existsSync2(join2(root, "packages", "cli", "package.json"))) {
168
+ return false;
169
+ }
170
+ return existsSync2(join2(root, "wrangler.jsonc")) || existsSync2(join2(root, "wrangler.jsonc.example")) || existsSync2(join2(root, "workers")) || existsSync2(join2(root, ".gitmodules"));
171
+ } catch {
172
+ return false;
173
+ }
174
+ }
175
+ function getRememberedMonorepoPath() {
176
+ return resolveHooxPath("config/monorepo.json");
177
+ }
178
+ function getRememberedMonorepoRoot() {
179
+ try {
180
+ const path = getRememberedMonorepoPath();
181
+ if (!existsSync2(path))
182
+ return null;
183
+ const raw = readFileSync2(path, "utf-8");
184
+ const data = JSON.parse(raw);
185
+ if (!data.root || typeof data.root !== "string")
186
+ return null;
187
+ const resolved = resolve(data.root);
188
+ return isHooxSetupRoot(resolved) ? resolved : null;
189
+ } catch {
190
+ return null;
191
+ }
192
+ }
193
+ function rememberMonorepoRoot(root) {
194
+ try {
195
+ const resolved = resolve(root);
196
+ if (!isHooxSetupRoot(resolved))
197
+ return false;
198
+ const configDir = getHooxConfigDir();
199
+ mkdirSync2(configDir, { recursive: true, mode: 448 });
200
+ try {
201
+ chmodSync2(configDir, 448);
202
+ } catch {}
203
+ const payload = {
204
+ root: resolved,
205
+ updatedAt: new Date().toISOString()
206
+ };
207
+ const path = getRememberedMonorepoPath();
208
+ writeFileSync2(path, JSON.stringify(payload, null, 2) + `
209
+ `, {
210
+ mode: 384
211
+ });
212
+ try {
213
+ chmodSync2(path, 384);
214
+ } catch {}
215
+ return true;
216
+ } catch {
217
+ return false;
218
+ }
219
+ }
220
+ function findHooxSetupRoot(startDir = process.cwd()) {
221
+ let dir = resolve(startDir);
222
+ for (;; ) {
223
+ if (isHooxSetupRoot(dir))
224
+ return dir;
225
+ const parent = dirname(dir);
226
+ if (parent === dir)
227
+ return null;
228
+ dir = parent;
229
+ }
230
+ }
231
+ function resolveHooxRuntimeRoot(options) {
232
+ const env = options?.env ?? process.env;
233
+ const cwd = resolve(options?.cwd ?? process.cwd());
234
+ const globalRepo = getHooxRepoPath();
235
+ const remembered = options?.skipRemembered ? null : getRememberedMonorepoRoot();
236
+ const envRepo = env.HOOX_REPO?.trim();
237
+ if (envRepo) {
238
+ const resolved = resolve(envRepo);
239
+ if (isHooxSetupRoot(resolved)) {
240
+ return {
241
+ root: resolved,
242
+ source: "env",
243
+ checked: {
244
+ env: resolved,
245
+ cwd: findHooxSetupRoot(cwd),
246
+ remembered,
247
+ global: globalRepo
248
+ }
249
+ };
250
+ }
251
+ return {
252
+ root: null,
253
+ source: "env",
254
+ checked: {
255
+ env: resolved,
256
+ cwd: findHooxSetupRoot(cwd),
257
+ remembered,
258
+ global: globalRepo
259
+ }
260
+ };
261
+ }
262
+ const local = findHooxSetupRoot(cwd);
263
+ if (local) {
264
+ return {
265
+ root: local,
266
+ source: "cwd",
267
+ checked: { cwd: local, remembered, global: globalRepo }
268
+ };
269
+ }
270
+ if (remembered) {
271
+ return {
272
+ root: remembered,
273
+ source: "remembered",
274
+ checked: { cwd: null, remembered, global: globalRepo }
275
+ };
276
+ }
277
+ if (isHooxSetupRoot(globalRepo)) {
278
+ return {
279
+ root: globalRepo,
280
+ source: "global",
281
+ checked: { cwd: null, remembered: null, global: globalRepo }
282
+ };
283
+ }
284
+ return {
285
+ root: null,
286
+ source: "none",
287
+ checked: { cwd: null, remembered: null, global: globalRepo }
288
+ };
289
+ }
290
+ function getTuiEntryCandidates(runtimeRoot) {
291
+ const root = resolve(runtimeRoot);
292
+ return [
293
+ join2(root, "packages", "tui", "src", "main.tsx"),
294
+ join2(root, "packages", "tui", "dist", "main.js"),
295
+ join2(root, "packages", "tui", "src", "main.ts")
296
+ ];
297
+ }
298
+ function resolveHooxPath(relativePath) {
299
+ if (!relativePath || typeof relativePath !== "string") {
300
+ throw new Error("relativePath must be a non-empty string");
301
+ }
302
+ if (relativePath.includes("..")) {
303
+ throw new Error(`Path traversal detected in relativePath: "${relativePath}"`);
304
+ }
305
+ const normalizedPath = relativePath.replace(/\\/g, "/");
306
+ const hooxHome = getHooxHome();
307
+ const fullPath = join2(hooxHome, normalizedPath);
308
+ const resolvedPath = resolve(fullPath);
309
+ const resolvedHome = resolve(hooxHome);
310
+ if (!resolvedPath.startsWith(resolvedHome)) {
311
+ throw new Error(`Resolved path "${resolvedPath}" is outside Hoox home directory`);
312
+ }
313
+ return createHooxPath(resolvedPath);
314
+ }
315
+ function isWithinHooxHome(path) {
316
+ try {
317
+ const hooxHome = getHooxHome();
318
+ const resolvedPath = resolve(path);
319
+ const resolvedHome = resolve(hooxHome);
320
+ return resolvedPath.startsWith(resolvedHome);
321
+ } catch {
322
+ return false;
323
+ }
324
+ }
325
+ function getRelativeHooxPath(absolutePath) {
326
+ try {
327
+ if (!isWithinHooxHome(absolutePath)) {
328
+ return null;
329
+ }
330
+ const hooxHome = getHooxHome();
331
+ const resolvedPath = resolve(absolutePath);
332
+ const resolvedHome = resolve(hooxHome);
333
+ const relativePath = resolvedPath.slice(resolvedHome.length);
334
+ return relativePath.startsWith("/") || relativePath.startsWith("\\") ? relativePath.slice(1) : relativePath;
335
+ } catch {
336
+ return null;
337
+ }
338
+ }
339
+ function getHooxRepoPath() {
340
+ return resolveHooxPath("repo");
341
+ }
342
+ function getHooxConfigDir() {
343
+ return resolveHooxPath("config");
344
+ }
345
+ function getHooxDataDir() {
346
+ return resolveHooxPath("data");
347
+ }
348
+ function getHooxWranglerPath() {
349
+ return resolveHooxPath("config/wrangler.jsonc");
350
+ }
351
+ function getHooxStatePath() {
352
+ return resolveHooxPath("data/state.json");
353
+ }
354
+
134
355
  // src/stores/config-store.ts
135
356
  import { create } from "zustand";
136
357
  import { immer } from "zustand/middleware/immer";
137
358
  import { persist, createJSONStorage } from "zustand/middleware";
138
- import { chmodSync as chmodSync2, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
139
- import { homedir as homedir2 } from "os";
140
- import { join as join2 } from "path";
359
+ import { chmodSync as chmodSync3, mkdirSync as mkdirSync3, existsSync as existsSync3, readFileSync as readFileSync3 } from "fs";
360
+ import { join as join3 } from "path";
361
+ function getTuiPreferencesPath() {
362
+ return join3(getHooxHome(), ".tui-state", "preferences.json");
363
+ }
364
+ function getLegacyConfigJsonPath() {
365
+ return join3(getHooxHome(), "config.json");
366
+ }
367
+ function extractZustandPrefsPayload(raw) {
368
+ try {
369
+ const parsed = JSON.parse(raw);
370
+ if (parsed && typeof parsed === "object" && parsed.state && typeof parsed.state === "object" && !Array.isArray(parsed.state) && (("theme" in parsed.state) || ("refreshIntervalMs" in parsed.state)) && !("apiToken" in parsed)) {
371
+ return raw;
372
+ }
373
+ } catch {}
374
+ return null;
375
+ }
141
376
  var bunConfigStorage = {
142
377
  getItem: async (_name) => {
143
378
  try {
144
- const file = Bun.file(join2(homedir2(), ".hoox", "config.json"));
145
- const exists = await file.exists();
146
- if (!exists)
147
- return null;
148
- return await file.text();
379
+ const prefsPath = getTuiPreferencesPath();
380
+ const prefsFile = Bun.file(prefsPath);
381
+ if (await prefsFile.exists()) {
382
+ return await prefsFile.text();
383
+ }
384
+ const legacyPath = getLegacyConfigJsonPath();
385
+ if (existsSync3(legacyPath)) {
386
+ const legacyRaw = readFileSync3(legacyPath, "utf-8");
387
+ const envelope = extractZustandPrefsPayload(legacyRaw);
388
+ if (envelope) {
389
+ await bunConfigStorage.setItem(_name, envelope);
390
+ return envelope;
391
+ }
392
+ }
393
+ return null;
149
394
  } catch {
150
395
  return null;
151
396
  }
152
397
  },
153
398
  setItem: async (_name, value) => {
154
- const dir = join2(homedir2(), ".hoox");
155
- if (!existsSync2(dir)) {
156
- mkdirSync2(dir, { recursive: true, mode: HOOX_DIR_MODE });
399
+ const home = getHooxHome();
400
+ const stateDir = join3(home, ".tui-state");
401
+ if (!existsSync3(home)) {
402
+ mkdirSync3(home, { recursive: true, mode: HOOX_DIR_MODE });
403
+ }
404
+ if (!existsSync3(stateDir)) {
405
+ mkdirSync3(stateDir, { recursive: true, mode: HOOX_DIR_MODE });
157
406
  }
158
407
  try {
159
- chmodSync2(dir, HOOX_DIR_MODE);
408
+ chmodSync3(home, HOOX_DIR_MODE);
409
+ chmodSync3(stateDir, HOOX_DIR_MODE);
160
410
  } catch {}
161
- const filePath = join2(dir, "config.json");
411
+ const filePath = getTuiPreferencesPath();
162
412
  await Bun.write(filePath, value);
163
413
  try {
164
- chmodSync2(filePath, HOOX_CONFIG_FILE_MODE);
414
+ chmodSync3(filePath, HOOX_CONFIG_FILE_MODE);
165
415
  } catch {}
166
416
  },
167
417
  removeItem: async (_name) => {}
@@ -233,7 +483,7 @@ var useConfigStore = create()(persist(immer((set) => ({
233
483
  state.notifications[channel] = !state.notifications[channel];
234
484
  })
235
485
  })), {
236
- name: "hoox-config",
486
+ name: "hoox-tui-prefs",
237
487
  storage: createJSONStorage(() => bunConfigStorage),
238
488
  partialize: (state) => ({
239
489
  theme: state.theme,
@@ -251,5 +501,6 @@ var useConfigStore = create()(persist(immer((set) => ({
251
501
  })
252
502
  }));
253
503
  export {
254
- useConfigStore
504
+ useConfigStore,
505
+ getTuiPreferencesPath
255
506
  };
@@ -41,6 +41,12 @@ interface ServiceActions {
41
41
  stopStreams: () => void;
42
42
  addAlert: (alert: Alert) => void;
43
43
  addAlerts: (alerts: Alert[]) => void;
44
+ /** Mark a single alert as acknowledged (UI triage). */
45
+ acknowledgeAlert: (id: string) => void;
46
+ /** Remove a single alert from the ring buffer. */
47
+ dismissAlert: (id: string) => void;
48
+ /** Clear the local log ring buffer (TUI display only). */
49
+ clearLogs: () => void;
44
50
  setConnectionStatus: (status: ConnectionStatus) => void;
45
51
  selectWorker: (id: string | null) => void;
46
52
  setWorkers: (workers: WorkerInfo[]) => void;
@@ -154,6 +160,9 @@ export declare const useServiceStore: import("zustand").UseBoundStore<Omit<impor
154
160
  stopStreams: () => void;
155
161
  addAlert: (alert: Alert) => void;
156
162
  addAlerts: (alerts: Alert[]) => void;
163
+ acknowledgeAlert: (id: string) => void;
164
+ dismissAlert: (id: string) => void;
165
+ clearLogs: () => void;
157
166
  setConnectionStatus: (status: ConnectionStatus) => void;
158
167
  selectWorker: (id: string | null) => void;
159
168
  setWorkers: (workers: WorkerInfo[]) => void;
@@ -247,6 +256,9 @@ export declare const useServiceStore: import("zustand").UseBoundStore<Omit<impor
247
256
  stopStreams: () => void;
248
257
  addAlert: (alert: Alert) => void;
249
258
  addAlerts: (alerts: Alert[]) => void;
259
+ acknowledgeAlert: (id: string) => void;
260
+ dismissAlert: (id: string) => void;
261
+ clearLogs: () => void;
250
262
  setConnectionStatus: (status: ConnectionStatus) => void;
251
263
  selectWorker: (id: string | null) => void;
252
264
  setWorkers: (workers: WorkerInfo[]) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"service-store.d.ts","sourceRoot":"","sources":["../../src/stores/service-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service-store.d.ts","sourceRoot":"","sources":["../../src/stores/service-store.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,11 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
17
 
18
18
  // src/operator-transport.ts
19
19
  function stripTrailingSlashes(url) {
20
- return url.replace(/\/+$/, "");
20
+ let end = url.length;
21
+ while (end > 0 && url.charCodeAt(end - 1) === 47) {
22
+ end -= 1;
23
+ }
24
+ return end === url.length ? url : url.slice(0, end);
21
25
  }
22
26
  function parseTransport(raw) {
23
27
  if (!raw)
@@ -64,7 +68,7 @@ function hasOperatorClientCredentials(profile) {
64
68
  return Boolean(profile.accessClientId && profile.accessClientSecret);
65
69
  }
66
70
  function operatorUrl(profile, path) {
67
- const base = profile.apiBase.replace(/\/+$/, "");
71
+ const base = stripTrailingSlashes(profile.apiBase);
68
72
  const p = path.startsWith("/") ? path : `/${path}`;
69
73
  return `${base}${p}`;
70
74
  }
@@ -273,6 +277,23 @@ function ringPush(arr, item, max) {
273
277
  var tradeStreamAbort = null;
274
278
  var logStreamAbort = null;
275
279
  var fetchWorkersGeneration = 0;
280
+ var reconnectTimer = null;
281
+ function clearReconnectTimer() {
282
+ if (reconnectTimer !== null) {
283
+ clearTimeout(reconnectTimer);
284
+ reconnectTimer = null;
285
+ }
286
+ }
287
+ function scheduleReconnect(delayMs) {
288
+ clearReconnectTimer();
289
+ if (delayMs < 0)
290
+ return;
291
+ reconnectTimer = setTimeout(() => {
292
+ reconnectTimer = null;
293
+ scheduledReconnectTick();
294
+ }, delayMs);
295
+ }
296
+ var scheduledReconnectTick = async () => {};
276
297
  var MAX_TRADES = 500;
277
298
  var MAX_ALERTS = 100;
278
299
  var MAX_LOGS = 1000;
@@ -307,6 +328,7 @@ var useServiceStore = create()(immer((set, get) => ({
307
328
  const data = await hooxFetch2("/v1/workers");
308
329
  if (gen !== fetchWorkersGeneration)
309
330
  return;
331
+ clearReconnectTimer();
310
332
  set((state) => {
311
333
  state.workers = data;
312
334
  state.lastUpdated = Date.now();
@@ -332,6 +354,7 @@ var useServiceStore = create()(immer((set, get) => ({
332
354
  timestamp: Date.now(),
333
355
  acknowledged: false
334
356
  });
357
+ let nextDelay = 0;
335
358
  set((state) => {
336
359
  state.lastError = msg;
337
360
  state.disconnectedAt = state.disconnectedAt ?? Date.now();
@@ -340,21 +363,26 @@ var useServiceStore = create()(immer((set, get) => ({
340
363
  state.retryCount = state.retryCount + 1;
341
364
  if (state.retryCount >= MAX_RETRIES2) {
342
365
  state.connectionStatus = "offline";
343
- state.lastError = `Connection lost after ${MAX_RETRIES2} retries`;
366
+ state.lastError = `${msg} (gave up after ${MAX_RETRIES2} retries)`;
367
+ state.reconnectDelay = 0;
344
368
  } else {
345
369
  state.reconnectDelay = getBackoffDelay(state.retryCount);
370
+ nextDelay = state.reconnectDelay;
346
371
  }
347
372
  } else if (state.connectionStatus === "reconnecting") {
348
373
  state.retryCount = state.retryCount + 1;
349
374
  if (state.retryCount >= MAX_RETRIES2) {
350
375
  state.connectionStatus = "offline";
351
- state.lastError = `Connection lost after ${MAX_RETRIES2} retries`;
376
+ state.lastError = `${msg} (gave up after ${MAX_RETRIES2} retries)`;
352
377
  state.reconnectDelay = 0;
353
378
  } else {
354
379
  state.reconnectDelay = getBackoffDelay(state.retryCount);
380
+ nextDelay = state.reconnectDelay;
355
381
  }
356
382
  }
357
383
  });
384
+ if (nextDelay > 0)
385
+ scheduleReconnect(nextDelay);
358
386
  }
359
387
  },
360
388
  streamTrades: async () => {
@@ -416,6 +444,17 @@ var useServiceStore = create()(immer((set, get) => ({
416
444
  const merged = [...state.alerts, ...alerts];
417
445
  state.alerts = merged.length > MAX_ALERTS ? merged.slice(merged.length - MAX_ALERTS) : merged;
418
446
  }),
447
+ acknowledgeAlert: (id) => set((state) => {
448
+ const hit = state.alerts.find((a) => a.id === id);
449
+ if (hit)
450
+ hit.acknowledged = true;
451
+ }),
452
+ dismissAlert: (id) => set((state) => {
453
+ state.alerts = state.alerts.filter((a) => a.id !== id);
454
+ }),
455
+ clearLogs: () => set((state) => {
456
+ state.logs = [];
457
+ }),
419
458
  setConnectionStatus: (status) => set((state) => {
420
459
  if (status === "connected") {
421
460
  state.retryCount = 0;
@@ -446,49 +485,69 @@ var useServiceStore = create()(immer((set, get) => ({
446
485
  state.metrics = metrics;
447
486
  state.lastUpdated = metrics.lastUpdated;
448
487
  }),
449
- handleConnectionSuccess: () => set((state) => {
450
- state.lastSuccessfulFetch = Date.now();
451
- state.retryCount = 0;
452
- state.lastError = null;
453
- state.lastErrorDetails = null;
454
- state.reconnectDelay = 0;
455
- state.disconnectedAt = null;
456
- state.connectionStatus = "connected";
457
- }),
458
- handleConnectionFailure: (errorMessage) => set((state) => {
459
- state.lastError = errorMessage;
460
- state.disconnectedAt = state.disconnectedAt ?? Date.now();
461
- if (state.connectionStatus === "connected" || state.connectionStatus === "polling") {
462
- state.connectionStatus = "reconnecting";
463
- state.retryCount = 1;
464
- state.reconnectDelay = getBackoffDelay(1);
465
- } else if (state.connectionStatus === "reconnecting") {
466
- state.retryCount = state.retryCount + 1;
467
- if (state.retryCount >= MAX_RETRIES2) {
468
- state.connectionStatus = "offline";
469
- state.lastError = `Connection lost after ${MAX_RETRIES2} retries`;
470
- state.reconnectDelay = 0;
471
- } else {
472
- state.reconnectDelay = getBackoffDelay(state.retryCount);
488
+ handleConnectionSuccess: () => {
489
+ clearReconnectTimer();
490
+ set((state) => {
491
+ state.lastSuccessfulFetch = Date.now();
492
+ state.retryCount = 0;
493
+ state.lastError = null;
494
+ state.lastErrorDetails = null;
495
+ state.reconnectDelay = 0;
496
+ state.disconnectedAt = null;
497
+ state.connectionStatus = "connected";
498
+ });
499
+ },
500
+ handleConnectionFailure: (errorMessage) => {
501
+ let nextDelay = 0;
502
+ set((state) => {
503
+ state.lastError = errorMessage;
504
+ state.disconnectedAt = state.disconnectedAt ?? Date.now();
505
+ if (state.connectionStatus === "connected" || state.connectionStatus === "polling") {
506
+ state.connectionStatus = "reconnecting";
507
+ state.retryCount = 1;
508
+ state.reconnectDelay = getBackoffDelay(1);
509
+ nextDelay = state.reconnectDelay;
510
+ } else if (state.connectionStatus === "reconnecting") {
511
+ state.retryCount = state.retryCount + 1;
512
+ if (state.retryCount >= MAX_RETRIES2) {
513
+ state.connectionStatus = "offline";
514
+ state.lastError = `${errorMessage} (gave up after ${MAX_RETRIES2} retries)`;
515
+ state.reconnectDelay = 0;
516
+ } else {
517
+ state.reconnectDelay = getBackoffDelay(state.retryCount);
518
+ nextDelay = state.reconnectDelay;
519
+ }
473
520
  }
474
- }
475
- }),
476
- resetRetries: () => set((state) => {
477
- state.retryCount = 0;
478
- state.lastError = null;
479
- state.lastErrorDetails = null;
480
- state.reconnectDelay = 0;
481
- state.disconnectedAt = null;
482
- }),
483
- forceRetry: () => set((state) => {
484
- if (state.connectionStatus === "offline") {
485
- state.connectionStatus = "polling";
521
+ });
522
+ if (nextDelay > 0)
523
+ scheduleReconnect(nextDelay);
524
+ },
525
+ resetRetries: () => {
526
+ clearReconnectTimer();
527
+ set((state) => {
486
528
  state.retryCount = 0;
487
529
  state.lastError = null;
488
530
  state.lastErrorDetails = null;
489
531
  state.reconnectDelay = 0;
532
+ state.disconnectedAt = null;
533
+ });
534
+ },
535
+ forceRetry: () => {
536
+ clearReconnectTimer();
537
+ const wasOffline = get().connectionStatus === "offline";
538
+ set((state) => {
539
+ if (state.connectionStatus === "offline") {
540
+ state.connectionStatus = "polling";
541
+ state.retryCount = 0;
542
+ state.lastError = null;
543
+ state.lastErrorDetails = null;
544
+ state.reconnectDelay = 0;
545
+ }
546
+ });
547
+ if (wasOffline) {
548
+ scheduleReconnect(0);
490
549
  }
491
- }),
550
+ },
492
551
  setLastErrorDetails: (details) => set((state) => {
493
552
  state.lastErrorDetails = details;
494
553
  state.lastError = details === null ? null : summarizeCliError(details);
@@ -511,6 +570,12 @@ var useServiceStore = create()(immer((set, get) => ({
511
570
  }, MAX_ALERTS);
512
571
  })
513
572
  })));
573
+ scheduledReconnectTick = async () => {
574
+ const status = useServiceStore.getState().connectionStatus;
575
+ if (status === "reconnecting" || status === "polling") {
576
+ await useServiceStore.getState().fetchWorkers();
577
+ }
578
+ };
514
579
  export {
515
580
  useServiceStore
516
581
  };
@@ -9,6 +9,11 @@ export interface UIState {
9
9
  modal: ModalState | null;
10
10
  commandPaletteOpen: boolean;
11
11
  previousView: ViewId | null;
12
+ /**
13
+ * Whether the status-bar CLI/connection diagnostics panel is expanded.
14
+ * Shared so palette / Ctrl+Shift+D / mouse can all toggle it.
15
+ */
16
+ statusErrorExpanded: boolean;
12
17
  }
13
18
  interface UIActions {
14
19
  setView: (view: ViewId) => void;
@@ -18,6 +23,9 @@ interface UIActions {
18
23
  showModal: (modal: ModalState) => void;
19
24
  dismissModal: () => void;
20
25
  goBack: () => void;
26
+ /** Toggle status-bar error diagnostics panel. */
27
+ toggleStatusErrorExpanded: () => void;
28
+ setStatusErrorExpanded: (expanded: boolean) => void;
21
29
  }
22
30
  export declare const useUIStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<UIState & UIActions>, "setState"> & {
23
31
  setState(nextStateOrUpdater: (UIState & UIActions) | Partial<UIState & UIActions> | ((state: {
@@ -33,6 +41,7 @@ export declare const useUIStore: import("zustand").UseBoundStore<Omit<import("zu
33
41
  } | null;
34
42
  commandPaletteOpen: boolean;
35
43
  previousView: ViewId | null;
44
+ statusErrorExpanded: boolean;
36
45
  setView: (view: ViewId) => void;
37
46
  toggleSidebar: () => void;
38
47
  openPalette: () => void;
@@ -40,6 +49,8 @@ export declare const useUIStore: import("zustand").UseBoundStore<Omit<import("zu
40
49
  showModal: (modal: ModalState) => void;
41
50
  dismissModal: () => void;
42
51
  goBack: () => void;
52
+ toggleStatusErrorExpanded: () => void;
53
+ setStatusErrorExpanded: (expanded: boolean) => void;
43
54
  }) => void), shouldReplace?: false): void;
44
55
  setState(nextStateOrUpdater: (UIState & UIActions) | ((state: {
45
56
  activeView: ViewId;
@@ -54,6 +65,7 @@ export declare const useUIStore: import("zustand").UseBoundStore<Omit<import("zu
54
65
  } | null;
55
66
  commandPaletteOpen: boolean;
56
67
  previousView: ViewId | null;
68
+ statusErrorExpanded: boolean;
57
69
  setView: (view: ViewId) => void;
58
70
  toggleSidebar: () => void;
59
71
  openPalette: () => void;
@@ -61,6 +73,8 @@ export declare const useUIStore: import("zustand").UseBoundStore<Omit<import("zu
61
73
  showModal: (modal: ModalState) => void;
62
74
  dismissModal: () => void;
63
75
  goBack: () => void;
76
+ toggleStatusErrorExpanded: () => void;
77
+ setStatusErrorExpanded: (expanded: boolean) => void;
64
78
  }) => void), shouldReplace: true): void;
65
79
  }>;
66
80
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ui-store.d.ts","sourceRoot":"","sources":["../../src/stores/ui-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAInD,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAID,UAAU,SAAS;IACjB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACvC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAgBD,eAAO,MAAM,UAAU;;oBAjCT,MAAM;yBACD,OAAO;;;;;;;;;4BAEJ,OAAO;sBACb,MAAM,GAAG,IAAI;iBAMlB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;uBAChB,MAAM,IAAI;qBACZ,MAAM,IAAI;sBACT,MAAM,IAAI;mBACb,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;sBACxB,MAAM,IAAI;gBAChB,MAAM,IAAI;;;oBAhBN,MAAM;yBACD,OAAO;;;;;;;;;4BAEJ,OAAO;sBACb,MAAM,GAAG,IAAI;iBAMlB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;uBAChB,MAAM,IAAI;qBACZ,MAAM,IAAI;sBACT,MAAM,IAAI;mBACb,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;sBACxB,MAAM,IAAI;gBAChB,MAAM,IAAI;;EAiEnB,CAAC"}
1
+ {"version":3,"file":"ui-store.d.ts","sourceRoot":"","sources":["../../src/stores/ui-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAInD,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;OAGG;IACH,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAID,UAAU,SAAS;IACjB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,SAAS,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IACvC,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,iDAAiD;IACjD,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,sBAAsB,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD;AAiBD,eAAO,MAAM,UAAU;;oBA1CT,MAAM;yBACD,OAAO;;;;;;;;;4BAEJ,OAAO;sBACb,MAAM,GAAG,IAAI;6BAKN,OAAO;iBAMnB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;uBAChB,MAAM,IAAI;qBACZ,MAAM,IAAI;sBACT,MAAM,IAAI;mBACb,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;sBACxB,MAAM,IAAI;gBAChB,MAAM,IAAI;mCAES,MAAM,IAAI;gCACb,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI;;;oBAxBvC,MAAM;yBACD,OAAO;;;;;;;;;4BAEJ,OAAO;sBACb,MAAM,GAAG,IAAI;6BAKN,OAAO;iBAMnB,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;uBAChB,MAAM,IAAI;qBACZ,MAAM,IAAI;sBACT,MAAM,IAAI;mBACb,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI;sBACxB,MAAM,IAAI;gBAChB,MAAM,IAAI;mCAES,MAAM,IAAI;gCACb,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI;;EA4EpD,CAAC"}