tokmon 0.20.2 → 0.20.4
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/{bootstrap-ink-KWHXVQYS.js → bootstrap-ink-3VQODLRG.js} +82 -41
- package/dist/{chunk-5IHAR2RZ.js → chunk-F7RJIR3Z.js} +33 -13
- package/dist/{chunk-7HJIP4U6.js → chunk-HSUYWU4V.js} +460 -279
- package/dist/cli.js +4 -4
- package/dist/{daemon-NVWX3RRK.js → daemon-O3R6R2R6.js} +2 -2
- package/dist/{daemon-handle-ZHECQZ6Q.js → daemon-handle-HLSKLMWU.js} +1 -1
- package/dist/{server-BXMRN774.js → server-6DGQI25X.js} +2 -2
- package/dist/web/assets/{breakdown-Dhq6Rqnu.js → breakdown-DFnPYZtA.js} +1 -1
- package/dist/web/assets/{chart-CDwPcOeB.js → chart-C8J22kR3.js} +1 -1
- package/dist/web/assets/index-B9eW55YB.js +105 -0
- package/dist/web/assets/{timeline-D0GFoRzM.js → timeline-BjoaOdbh.js} +1 -1
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/dist/web/assets/index-Bqe9b8BZ.js +0 -105
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
systemTimezone,
|
|
19
19
|
time,
|
|
20
20
|
tokens
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-HSUYWU4V.js";
|
|
22
22
|
import {
|
|
23
23
|
COLOR_PALETTE,
|
|
24
24
|
DEFAULTS,
|
|
@@ -1670,12 +1670,11 @@ async function socketLayerFor(url, transport) {
|
|
|
1670
1670
|
);
|
|
1671
1671
|
}
|
|
1672
1672
|
function retryPolicy(options) {
|
|
1673
|
-
const attempts = options.reconnectAttempts ?? 5;
|
|
1674
1673
|
const baseDelay = options.reconnectBaseDelayMs ?? 250;
|
|
1675
|
-
|
|
1676
|
-
Schedule.
|
|
1677
|
-
(retryCount) => Effect.succeed(Duration.millis(Math.min(baseDelay * (retryCount + 1), 2500)))
|
|
1674
|
+
const policy = Schedule.exponential(Duration.millis(baseDelay), 1.5).pipe(
|
|
1675
|
+
Schedule.either(Schedule.spaced(Duration.millis(2500)))
|
|
1678
1676
|
);
|
|
1677
|
+
return typeof options.reconnectAttempts === "number" ? policy.pipe(Schedule.both(Schedule.recurs(options.reconnectAttempts))) : policy;
|
|
1679
1678
|
}
|
|
1680
1679
|
function createDaemonRpcClient(baseUrl, options = {}) {
|
|
1681
1680
|
const url = toWsUrl(baseUrl, options.wsToken);
|
|
@@ -1686,6 +1685,13 @@ function createDaemonRpcClient(baseUrl, options = {}) {
|
|
|
1686
1685
|
const setConn = (state, error) => {
|
|
1687
1686
|
options.onConn?.(state, error);
|
|
1688
1687
|
};
|
|
1688
|
+
const resetSession = (active) => {
|
|
1689
|
+
const dead = active ?? session;
|
|
1690
|
+
if (active === void 0 || active === session) session = null;
|
|
1691
|
+
sessionPromise = null;
|
|
1692
|
+
if (dead) void dead.runtime.dispose().catch(() => {
|
|
1693
|
+
});
|
|
1694
|
+
};
|
|
1689
1695
|
const makeProtocolLayer = async () => {
|
|
1690
1696
|
const socketLayer = await socketLayerFor(url, options.transport);
|
|
1691
1697
|
const connectionHooksLayer = Layer.succeed(
|
|
@@ -1695,7 +1701,10 @@ function createDaemonRpcClient(baseUrl, options = {}) {
|
|
|
1695
1701
|
setConn("live");
|
|
1696
1702
|
}),
|
|
1697
1703
|
onDisconnect: Effect.sync(() => {
|
|
1698
|
-
if (!closed)
|
|
1704
|
+
if (!closed) {
|
|
1705
|
+
setConn("reconnecting");
|
|
1706
|
+
resetSession();
|
|
1707
|
+
}
|
|
1699
1708
|
})
|
|
1700
1709
|
})
|
|
1701
1710
|
);
|
|
@@ -1749,7 +1758,10 @@ function createDaemonRpcClient(baseUrl, options = {}) {
|
|
|
1749
1758
|
TokmonRpcClient.use((client) => effectFor(client))
|
|
1750
1759
|
);
|
|
1751
1760
|
} catch (error) {
|
|
1752
|
-
if (!closed)
|
|
1761
|
+
if (!closed) {
|
|
1762
|
+
resetSession(active);
|
|
1763
|
+
setConn("error", error);
|
|
1764
|
+
}
|
|
1753
1765
|
throw error;
|
|
1754
1766
|
}
|
|
1755
1767
|
};
|
|
@@ -1758,42 +1770,71 @@ function createDaemonRpcClient(baseUrl, options = {}) {
|
|
|
1758
1770
|
};
|
|
1759
1771
|
let fiber = null;
|
|
1760
1772
|
let unsubscribed = false;
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1773
|
+
let retryTimer = null;
|
|
1774
|
+
const stopFiber = () => {
|
|
1775
|
+
if (!fiber) return;
|
|
1776
|
+
const current = fiber;
|
|
1777
|
+
fiber = null;
|
|
1778
|
+
fibers.delete(current);
|
|
1779
|
+
void (session?.runtime.runPromise(Fiber.interrupt(current)) ?? Effect.runPromise(Fiber.interrupt(current))).catch(() => {
|
|
1780
|
+
});
|
|
1781
|
+
};
|
|
1782
|
+
const scheduleRetry = () => {
|
|
1783
|
+
if (closed || unsubscribed || retryTimer) return;
|
|
1784
|
+
retryTimer = setTimeout(() => {
|
|
1785
|
+
retryTimer = null;
|
|
1786
|
+
start();
|
|
1787
|
+
}, options.reconnectBaseDelayMs ?? 250);
|
|
1788
|
+
retryTimer.unref?.();
|
|
1789
|
+
};
|
|
1790
|
+
const start = () => {
|
|
1791
|
+
void (async () => {
|
|
1792
|
+
try {
|
|
1793
|
+
const active = await ensureSession();
|
|
1794
|
+
if (closed || unsubscribed) return;
|
|
1795
|
+
fiber = active.runtime.runFork(
|
|
1796
|
+
TokmonRpcClient.use(
|
|
1797
|
+
(client) => streamFor(client).pipe(
|
|
1798
|
+
Stream.runForEach(
|
|
1799
|
+
(value) => Effect.sync(() => {
|
|
1800
|
+
try {
|
|
1801
|
+
onValue(value);
|
|
1802
|
+
} catch {
|
|
1803
|
+
}
|
|
1804
|
+
})
|
|
1805
|
+
)
|
|
1775
1806
|
)
|
|
1776
|
-
)
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1807
|
+
).pipe(Effect.catchCause(
|
|
1808
|
+
(cause) => Effect.sync(() => {
|
|
1809
|
+
if (!closed && !unsubscribed) {
|
|
1810
|
+
resetSession(active);
|
|
1811
|
+
setConn("error", Cause.squash(cause));
|
|
1812
|
+
scheduleRetry();
|
|
1813
|
+
}
|
|
1814
|
+
})
|
|
1815
|
+
))
|
|
1816
|
+
);
|
|
1817
|
+
fibers.add(fiber);
|
|
1818
|
+
fiber.addObserver(() => {
|
|
1819
|
+
if (fiber) fibers.delete(fiber);
|
|
1820
|
+
});
|
|
1821
|
+
} catch (error) {
|
|
1822
|
+
if (!closed && !unsubscribed) {
|
|
1823
|
+
resetSession();
|
|
1824
|
+
setConn("error", error);
|
|
1825
|
+
scheduleRetry();
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
})();
|
|
1829
|
+
};
|
|
1830
|
+
start();
|
|
1791
1831
|
return () => {
|
|
1792
1832
|
unsubscribed = true;
|
|
1793
|
-
if (
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
}
|
|
1833
|
+
if (retryTimer) {
|
|
1834
|
+
clearTimeout(retryTimer);
|
|
1835
|
+
retryTimer = null;
|
|
1836
|
+
}
|
|
1837
|
+
stopFiber();
|
|
1797
1838
|
};
|
|
1798
1839
|
};
|
|
1799
1840
|
return {
|
|
@@ -3194,7 +3235,7 @@ function App({ interval: cliInterval, initialConfig, baseUrl = null, wsToken = n
|
|
|
3194
3235
|
if (webStartingRef.current) return;
|
|
3195
3236
|
webStartingRef.current = true;
|
|
3196
3237
|
try {
|
|
3197
|
-
const { startWebServer } = await import("./server-
|
|
3238
|
+
const { startWebServer } = await import("./server-6DGQI25X.js");
|
|
3198
3239
|
const ctrl = await startWebServer({ config: cfg, log: false });
|
|
3199
3240
|
webRef.current = ctrl;
|
|
3200
3241
|
openUrl(ctrl.url);
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
detectProviders,
|
|
9
9
|
fetchPeak,
|
|
10
10
|
resolveTimezone
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-HSUYWU4V.js";
|
|
12
12
|
import {
|
|
13
13
|
cacheDir,
|
|
14
14
|
expandHome,
|
|
@@ -319,6 +319,14 @@ var PEAK_INTERVAL_MS = 3e5;
|
|
|
319
319
|
var IDLE_PAUSE_MS = 6e4;
|
|
320
320
|
var SNAPSHOT_CACHE_THROTTLE_MS = 2e4;
|
|
321
321
|
var REVEAL_THROTTLE_MS = 500;
|
|
322
|
+
var FETCH_TIMEOUT_MS = 3e4;
|
|
323
|
+
var withTimeout = (p, ms) => Promise.race([
|
|
324
|
+
p,
|
|
325
|
+
new Promise((_, reject) => {
|
|
326
|
+
const t = setTimeout(() => reject(new Error("fetch timeout")), ms);
|
|
327
|
+
t.unref?.();
|
|
328
|
+
})
|
|
329
|
+
]);
|
|
322
330
|
function createDataEngine(opts) {
|
|
323
331
|
const { version } = opts;
|
|
324
332
|
let tz = opts.tz;
|
|
@@ -438,7 +446,7 @@ function createDataEngine(opts) {
|
|
|
438
446
|
let dashboard = null;
|
|
439
447
|
let ok = true;
|
|
440
448
|
try {
|
|
441
|
-
dashboard = await fetchAccountSummary(r.account, tz);
|
|
449
|
+
dashboard = await withTimeout(fetchAccountSummary(r.account, tz), FETCH_TIMEOUT_MS);
|
|
442
450
|
} catch {
|
|
443
451
|
ok = false;
|
|
444
452
|
}
|
|
@@ -475,7 +483,7 @@ function createDataEngine(opts) {
|
|
|
475
483
|
let table = null;
|
|
476
484
|
let ok = true;
|
|
477
485
|
try {
|
|
478
|
-
table = await fetchAccountTable(r.account, tz);
|
|
486
|
+
table = await withTimeout(fetchAccountTable(r.account, tz), FETCH_TIMEOUT_MS);
|
|
479
487
|
} catch {
|
|
480
488
|
ok = false;
|
|
481
489
|
}
|
|
@@ -512,7 +520,7 @@ function createDataEngine(opts) {
|
|
|
512
520
|
let result = null;
|
|
513
521
|
let ok = true;
|
|
514
522
|
try {
|
|
515
|
-
result = await fetchAccountBilling(r.account);
|
|
523
|
+
result = await withTimeout(fetchAccountBilling(r.account), FETCH_TIMEOUT_MS);
|
|
516
524
|
} catch {
|
|
517
525
|
ok = false;
|
|
518
526
|
}
|
|
@@ -702,6 +710,10 @@ import { join as join3, resolve as resolvePath, isAbsolute, sep as sep2 } from "
|
|
|
702
710
|
function isContained(root, target) {
|
|
703
711
|
return target === root || target.startsWith(root + sep2);
|
|
704
712
|
}
|
|
713
|
+
function parentFor(root, abs) {
|
|
714
|
+
const parentResolved = resolvePath(abs, "..");
|
|
715
|
+
return abs === root || !isContained(root, parentResolved) ? null : parentResolved;
|
|
716
|
+
}
|
|
705
717
|
async function listHomeDirectory(rawPath) {
|
|
706
718
|
const root = resolvePath(homedir());
|
|
707
719
|
const expanded = expandHome(rawPath || "~");
|
|
@@ -714,9 +726,19 @@ async function listHomeDirectory(rawPath) {
|
|
|
714
726
|
real = lexical;
|
|
715
727
|
}
|
|
716
728
|
const abs = isContained(root, real) ? real : root;
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
729
|
+
let st;
|
|
730
|
+
try {
|
|
731
|
+
st = await stat2(abs);
|
|
732
|
+
} catch {
|
|
733
|
+
return { path: abs, parent: parentFor(root, abs), entries: [] };
|
|
734
|
+
}
|
|
735
|
+
if (!st.isDirectory()) return { path: abs, parent: parentFor(root, abs), entries: [] };
|
|
736
|
+
let dirents;
|
|
737
|
+
try {
|
|
738
|
+
dirents = await readdir(abs, { withFileTypes: true });
|
|
739
|
+
} catch {
|
|
740
|
+
return { path: abs, parent: parentFor(root, abs), entries: [] };
|
|
741
|
+
}
|
|
720
742
|
const entries = [];
|
|
721
743
|
for (const d of dirents) {
|
|
722
744
|
if (d.name.startsWith(".")) continue;
|
|
@@ -739,9 +761,7 @@ async function listHomeDirectory(rawPath) {
|
|
|
739
761
|
entries.push({ name: d.name, path: full, dir });
|
|
740
762
|
}
|
|
741
763
|
entries.sort((a, b) => a.dir === b.dir ? a.name.localeCompare(b.name) : a.dir ? -1 : 1);
|
|
742
|
-
|
|
743
|
-
const parent = abs === root || !isContained(root, parentResolved) ? null : parentResolved;
|
|
744
|
-
return { path: abs, parent, entries };
|
|
764
|
+
return { path: abs, parent: parentFor(root, abs), entries };
|
|
745
765
|
}
|
|
746
766
|
|
|
747
767
|
// src/web/ws.ts
|
|
@@ -841,12 +861,12 @@ async function mountWsRpc(server, deps) {
|
|
|
841
861
|
const wss = new NodeWS.WebSocketServer({ noServer: true });
|
|
842
862
|
const handlersLayer = TokmonRpcGroup.toLayer(
|
|
843
863
|
TokmonRpcGroup.of({
|
|
844
|
-
[TOKMON_WS_METHODS.getConfig]: () => Effect.
|
|
845
|
-
[TOKMON_WS_METHODS.setConfig]: (config) => Effect.
|
|
864
|
+
[TOKMON_WS_METHODS.getConfig]: () => Effect.tryPromise(() => Promise.resolve(deps.state.config ?? loadConfig())),
|
|
865
|
+
[TOKMON_WS_METHODS.setConfig]: (config) => Effect.tryPromise(() => applyConfigUpdate(deps.engine, deps.state, config)),
|
|
846
866
|
[TOKMON_WS_METHODS.refresh]: ({ scope: scope2 }) => Effect.sync(() => {
|
|
847
867
|
deps.engine.refresh(scope2);
|
|
848
868
|
}),
|
|
849
|
-
[TOKMON_WS_METHODS.browseFs]: ({ path }) => Effect.
|
|
869
|
+
[TOKMON_WS_METHODS.browseFs]: ({ path }) => Effect.tryPromise(() => listHomeDirectory(path)),
|
|
850
870
|
[TOKMON_WS_METHODS.snapshot]: () => snapshotStream(deps.engine),
|
|
851
871
|
[TOKMON_WS_METHODS.config]: () => configStream(deps.engine)
|
|
852
872
|
})
|