@hoox-sh/hoox-shared 1.2.1 → 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.
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +223 -59
- package/dist/path-utils.d.ts +35 -4
- package/dist/path-utils.d.ts.map +1 -1
- package/dist/path-utils.js +72 -5
- package/dist/session.js +69 -5
- package/dist/stores/config-store.d.ts +2 -0
- package/dist/stores/config-store.d.ts.map +1 -1
- package/dist/stores/config-store.js +267 -16
- package/dist/stores/service-store.d.ts +12 -0
- package/dist/stores/service-store.d.ts.map +1 -1
- package/dist/stores/service-store.js +100 -39
- package/dist/stores/ui-store.d.ts +14 -0
- package/dist/stores/ui-store.d.ts.map +1 -1
- package/dist/stores/ui-store.js +8 -1
- package/package.json +1 -1
|
@@ -277,6 +277,23 @@ function ringPush(arr, item, max) {
|
|
|
277
277
|
var tradeStreamAbort = null;
|
|
278
278
|
var logStreamAbort = null;
|
|
279
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 () => {};
|
|
280
297
|
var MAX_TRADES = 500;
|
|
281
298
|
var MAX_ALERTS = 100;
|
|
282
299
|
var MAX_LOGS = 1000;
|
|
@@ -311,6 +328,7 @@ var useServiceStore = create()(immer((set, get) => ({
|
|
|
311
328
|
const data = await hooxFetch2("/v1/workers");
|
|
312
329
|
if (gen !== fetchWorkersGeneration)
|
|
313
330
|
return;
|
|
331
|
+
clearReconnectTimer();
|
|
314
332
|
set((state) => {
|
|
315
333
|
state.workers = data;
|
|
316
334
|
state.lastUpdated = Date.now();
|
|
@@ -336,6 +354,7 @@ var useServiceStore = create()(immer((set, get) => ({
|
|
|
336
354
|
timestamp: Date.now(),
|
|
337
355
|
acknowledged: false
|
|
338
356
|
});
|
|
357
|
+
let nextDelay = 0;
|
|
339
358
|
set((state) => {
|
|
340
359
|
state.lastError = msg;
|
|
341
360
|
state.disconnectedAt = state.disconnectedAt ?? Date.now();
|
|
@@ -344,21 +363,26 @@ var useServiceStore = create()(immer((set, get) => ({
|
|
|
344
363
|
state.retryCount = state.retryCount + 1;
|
|
345
364
|
if (state.retryCount >= MAX_RETRIES2) {
|
|
346
365
|
state.connectionStatus = "offline";
|
|
347
|
-
state.lastError =
|
|
366
|
+
state.lastError = `${msg} (gave up after ${MAX_RETRIES2} retries)`;
|
|
367
|
+
state.reconnectDelay = 0;
|
|
348
368
|
} else {
|
|
349
369
|
state.reconnectDelay = getBackoffDelay(state.retryCount);
|
|
370
|
+
nextDelay = state.reconnectDelay;
|
|
350
371
|
}
|
|
351
372
|
} else if (state.connectionStatus === "reconnecting") {
|
|
352
373
|
state.retryCount = state.retryCount + 1;
|
|
353
374
|
if (state.retryCount >= MAX_RETRIES2) {
|
|
354
375
|
state.connectionStatus = "offline";
|
|
355
|
-
state.lastError =
|
|
376
|
+
state.lastError = `${msg} (gave up after ${MAX_RETRIES2} retries)`;
|
|
356
377
|
state.reconnectDelay = 0;
|
|
357
378
|
} else {
|
|
358
379
|
state.reconnectDelay = getBackoffDelay(state.retryCount);
|
|
380
|
+
nextDelay = state.reconnectDelay;
|
|
359
381
|
}
|
|
360
382
|
}
|
|
361
383
|
});
|
|
384
|
+
if (nextDelay > 0)
|
|
385
|
+
scheduleReconnect(nextDelay);
|
|
362
386
|
}
|
|
363
387
|
},
|
|
364
388
|
streamTrades: async () => {
|
|
@@ -420,6 +444,17 @@ var useServiceStore = create()(immer((set, get) => ({
|
|
|
420
444
|
const merged = [...state.alerts, ...alerts];
|
|
421
445
|
state.alerts = merged.length > MAX_ALERTS ? merged.slice(merged.length - MAX_ALERTS) : merged;
|
|
422
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
|
+
}),
|
|
423
458
|
setConnectionStatus: (status) => set((state) => {
|
|
424
459
|
if (status === "connected") {
|
|
425
460
|
state.retryCount = 0;
|
|
@@ -450,49 +485,69 @@ var useServiceStore = create()(immer((set, get) => ({
|
|
|
450
485
|
state.metrics = metrics;
|
|
451
486
|
state.lastUpdated = metrics.lastUpdated;
|
|
452
487
|
}),
|
|
453
|
-
handleConnectionSuccess: () =>
|
|
454
|
-
|
|
455
|
-
state
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
state.
|
|
469
|
-
|
|
470
|
-
state.
|
|
471
|
-
|
|
472
|
-
state.
|
|
473
|
-
state.
|
|
474
|
-
state.reconnectDelay
|
|
475
|
-
} else {
|
|
476
|
-
state.
|
|
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
|
+
}
|
|
477
520
|
}
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
state
|
|
485
|
-
state.disconnectedAt = null;
|
|
486
|
-
}),
|
|
487
|
-
forceRetry: () => set((state) => {
|
|
488
|
-
if (state.connectionStatus === "offline") {
|
|
489
|
-
state.connectionStatus = "polling";
|
|
521
|
+
});
|
|
522
|
+
if (nextDelay > 0)
|
|
523
|
+
scheduleReconnect(nextDelay);
|
|
524
|
+
},
|
|
525
|
+
resetRetries: () => {
|
|
526
|
+
clearReconnectTimer();
|
|
527
|
+
set((state) => {
|
|
490
528
|
state.retryCount = 0;
|
|
491
529
|
state.lastError = null;
|
|
492
530
|
state.lastErrorDetails = null;
|
|
493
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);
|
|
494
549
|
}
|
|
495
|
-
}
|
|
550
|
+
},
|
|
496
551
|
setLastErrorDetails: (details) => set((state) => {
|
|
497
552
|
state.lastErrorDetails = details;
|
|
498
553
|
state.lastError = details === null ? null : summarizeCliError(details);
|
|
@@ -515,6 +570,12 @@ var useServiceStore = create()(immer((set, get) => ({
|
|
|
515
570
|
}, MAX_ALERTS);
|
|
516
571
|
})
|
|
517
572
|
})));
|
|
573
|
+
scheduledReconnectTick = async () => {
|
|
574
|
+
const status = useServiceStore.getState().connectionStatus;
|
|
575
|
+
if (status === "reconnecting" || status === "polling") {
|
|
576
|
+
await useServiceStore.getState().fetchWorkers();
|
|
577
|
+
}
|
|
578
|
+
};
|
|
518
579
|
export {
|
|
519
580
|
useServiceStore
|
|
520
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;
|
|
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"}
|
package/dist/stores/ui-store.js
CHANGED
|
@@ -24,7 +24,8 @@ var initialState = {
|
|
|
24
24
|
sidebarExpanded: true,
|
|
25
25
|
modal: null,
|
|
26
26
|
commandPaletteOpen: false,
|
|
27
|
-
previousView: null
|
|
27
|
+
previousView: null,
|
|
28
|
+
statusErrorExpanded: false
|
|
28
29
|
};
|
|
29
30
|
var useUIStore = create()(immer((set) => ({
|
|
30
31
|
...initialState,
|
|
@@ -55,6 +56,12 @@ var useUIStore = create()(immer((set) => ({
|
|
|
55
56
|
state.activeView = state.previousView;
|
|
56
57
|
state.previousView = null;
|
|
57
58
|
}
|
|
59
|
+
}),
|
|
60
|
+
toggleStatusErrorExpanded: () => set((state) => {
|
|
61
|
+
state.statusErrorExpanded = !state.statusErrorExpanded;
|
|
62
|
+
}),
|
|
63
|
+
setStatusErrorExpanded: (expanded) => set((state) => {
|
|
64
|
+
state.statusErrorExpanded = expanded;
|
|
58
65
|
})
|
|
59
66
|
})));
|
|
60
67
|
export {
|