@thingd/cli 0.52.10 → 0.53.1
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.map +1 -1
- package/dist/index.js +4 -0
- package/dist/interactive.d.ts.map +1 -1
- package/dist/interactive.js +79 -77
- package/package.json +2 -2
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAQA,OAAO,EAUL,MAAM,EACN,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AASrB,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEjD,KAAK,YAAY,GAAG;IAClB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,KAAK,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC;AAE1C,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAsCF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAwFF,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CA8EjB;AAk6BD,wBAAsB,MAAM,CAC1B,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CAef;AA4BD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAQA,OAAO,EAUL,MAAM,EACN,KAAK,YAAY,EAClB,MAAM,aAAa,CAAC;AASrB,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEjD,KAAK,YAAY,GAAG;IAClB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,KAAK,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC;AAE1C,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAsCF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAwFF,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CA8EjB;AAk6BD,wBAAsB,MAAM,CAC1B,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CAef;AA4BD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,iBAAiB,CAqDxE;AAiDD,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/E;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAGlF;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMrE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnF;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMrF;AAyFD,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAEpF;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAElE"}
|
package/dist/index.js
CHANGED
|
@@ -959,6 +959,10 @@ export function resolveConnection(context) {
|
|
|
959
959
|
}
|
|
960
960
|
// Fall back to saved cloud config when no explicit URL/token is provided
|
|
961
961
|
const cloudCfg = cloud && !url ? readCloudConfig() : null;
|
|
962
|
+
if (driver === "cloud" && !url && !cloudCfg) {
|
|
963
|
+
context.stderr.write(`${pc.red("Not logged in.")} Run ${pc.cyan("thingd cloud login")} first, or use ${pc.cyan("--url")} and ${pc.cyan("--auth-token")} to connect directly.\n`);
|
|
964
|
+
throw new Error("not_logged_in");
|
|
965
|
+
}
|
|
962
966
|
const resolvedAuthToken = stringFlag(context.parsed, "auth-token") ??
|
|
963
967
|
context.env.THINGD_AUTH_TOKEN ??
|
|
964
968
|
cloudCfg?.apiKey ??
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../src/interactive.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../src/interactive.ts"],"names":[],"mappings":"AAolEA,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CA0FvD"}
|
package/dist/interactive.js
CHANGED
|
@@ -92,6 +92,7 @@ let viewerScroll = 0;
|
|
|
92
92
|
let loadedItemId = "";
|
|
93
93
|
let loadTimer = null;
|
|
94
94
|
let pollTimer = null;
|
|
95
|
+
let polling = false;
|
|
95
96
|
let keypressHandler = null;
|
|
96
97
|
let formState = null;
|
|
97
98
|
function openForm(title, fields, onSubmit, keepViewer) {
|
|
@@ -198,75 +199,47 @@ function formatUptime(ms) {
|
|
|
198
199
|
}
|
|
199
200
|
async function fetchResourcesFallback() {
|
|
200
201
|
cloudError = null;
|
|
202
|
+
// Collections and streams — parallel fetch
|
|
203
|
+
let nativeCollections;
|
|
204
|
+
let nativeStreams;
|
|
201
205
|
try {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const defaultStrs = new Set();
|
|
207
|
-
for (const c of nativeCollections) {
|
|
208
|
-
defaultCols.add(c);
|
|
209
|
-
}
|
|
210
|
-
for (const s of nativeStreams) {
|
|
211
|
-
defaultStrs.add(s);
|
|
212
|
-
}
|
|
213
|
-
collections = Array.from(defaultCols).sort();
|
|
214
|
-
streams = Array.from(defaultStrs).sort();
|
|
206
|
+
[nativeCollections, nativeStreams] = await Promise.all([
|
|
207
|
+
db.listCollections(),
|
|
208
|
+
db.listStreams(),
|
|
209
|
+
]);
|
|
215
210
|
}
|
|
216
211
|
catch (err) {
|
|
217
212
|
const msg = err instanceof Error ? err.message : String(err);
|
|
218
213
|
cloudError = `Failed to load resources: ${msg}`;
|
|
219
|
-
|
|
220
|
-
|
|
214
|
+
nativeCollections = [];
|
|
215
|
+
nativeStreams = [];
|
|
221
216
|
if (viewerLines.length === 1 && viewerLines[0] === "Select an item to view details.") {
|
|
222
217
|
viewerLines = [pc.yellow(cloudError), pc.dim("Press 'r' to retry or 's' to switch driver.")];
|
|
223
218
|
}
|
|
224
219
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
catch {
|
|
248
|
-
totalDeadJobsCount = 0;
|
|
249
|
-
}
|
|
250
|
-
// Queues
|
|
251
|
-
try {
|
|
252
|
-
const listed = await db.listQueues();
|
|
253
|
-
queues = (listed ?? []).sort();
|
|
254
|
-
}
|
|
255
|
-
catch (err) {
|
|
256
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
257
|
-
cloudError = cloudError ?? `Failed to load queues: ${msg}`;
|
|
258
|
-
queues = [];
|
|
259
|
-
}
|
|
260
|
-
// Link count
|
|
261
|
-
try {
|
|
262
|
-
totalLinksCount = await db.countLinks();
|
|
263
|
-
}
|
|
264
|
-
catch {
|
|
265
|
-
totalLinksCount = 0;
|
|
266
|
-
}
|
|
267
|
-
// Populate objectsByCollection from live data
|
|
220
|
+
collections = [...new Set(nativeCollections)].sort();
|
|
221
|
+
streams = [...new Set(nativeStreams)].sort();
|
|
222
|
+
// Counts, queues, links — all parallel, each with independent error handling
|
|
223
|
+
const [objCount, evtCount, activeCount, deadCount, listedQueues, linkCount] = await Promise.all([
|
|
224
|
+
db.countObjects().catch(() => 0),
|
|
225
|
+
db.countEvents().catch(() => 0),
|
|
226
|
+
db.countActiveJobs().catch(() => 0),
|
|
227
|
+
db.countDeadJobs().catch(() => 0),
|
|
228
|
+
db.listQueues().catch(() => {
|
|
229
|
+
cloudError = cloudError ?? "Failed to load queues";
|
|
230
|
+
return [];
|
|
231
|
+
}),
|
|
232
|
+
db.countLinks().catch(() => 0),
|
|
233
|
+
]);
|
|
234
|
+
totalObjects = objCount;
|
|
235
|
+
totalEventsCount = evtCount;
|
|
236
|
+
totalActiveJobsCount = activeCount;
|
|
237
|
+
totalDeadJobsCount = deadCount;
|
|
238
|
+
queues = [...new Set(listedQueues ?? [])].sort();
|
|
239
|
+
totalLinksCount = linkCount;
|
|
240
|
+
// Objects per collection — parallel
|
|
268
241
|
objectsByCollection.clear();
|
|
269
|
-
|
|
242
|
+
await Promise.all(collections.map(async (col) => {
|
|
270
243
|
try {
|
|
271
244
|
const list = await db.listObjects(col);
|
|
272
245
|
objectsByCollection.set(col, list.map((o) => o.id));
|
|
@@ -274,7 +247,7 @@ async function fetchResourcesFallback() {
|
|
|
274
247
|
catch {
|
|
275
248
|
objectsByCollection.set(col, []);
|
|
276
249
|
}
|
|
277
|
-
}
|
|
250
|
+
}));
|
|
278
251
|
}
|
|
279
252
|
async function fetchResources() {
|
|
280
253
|
if (driver === "native" && dbPath) {
|
|
@@ -327,9 +300,8 @@ async function fetchResources() {
|
|
|
327
300
|
const prevEvents = eventsHistory.length > 0
|
|
328
301
|
? (eventsHistory[eventsHistory.length - 1] ?? totalEventsCount)
|
|
329
302
|
: totalEventsCount;
|
|
330
|
-
|
|
331
|
-
const
|
|
332
|
-
const eventAppendRate = Math.max(0, Math.round((totalEventsCount - prevEvents) / 2));
|
|
303
|
+
const objectWriteRate = Math.max(0, Math.round((totalObjects - prevObjects) / 10));
|
|
304
|
+
const eventAppendRate = Math.max(0, Math.round((totalEventsCount - prevEvents) / 10));
|
|
333
305
|
// Push Histories with Initial Pre-population to prevent misleading growth wiggles
|
|
334
306
|
if (objectsHistory.length === 0) {
|
|
335
307
|
objectsHistory = new Array(60).fill(totalObjects);
|
|
@@ -1761,7 +1733,9 @@ async function handleConnect(node) {
|
|
|
1761
1733
|
const cloudCfg = selectedDriver === "cloud" ? readCloudConfig() : null;
|
|
1762
1734
|
const baseUrl = cloudCfg?.url ?? "https://api.thingd.cloud";
|
|
1763
1735
|
const isCloudWithConfig = selectedDriver === "cloud" && cloudCfg?.token;
|
|
1764
|
-
openForm(
|
|
1736
|
+
openForm(selectedDriver === "cloud" && !isCloudWithConfig
|
|
1737
|
+
? `Connect to ${selectedDriver} — enter credentials below or run ${pc.cyan("thingd cloud login")} first`
|
|
1738
|
+
: `Connect to ${selectedDriver}`, [
|
|
1765
1739
|
...(selectedDriver === "cloud"
|
|
1766
1740
|
? isCloudWithConfig
|
|
1767
1741
|
? [
|
|
@@ -1974,24 +1948,52 @@ export async function runInteractiveCli() {
|
|
|
1974
1948
|
}
|
|
1975
1949
|
}
|
|
1976
1950
|
}
|
|
1951
|
+
else {
|
|
1952
|
+
viewerLines = [
|
|
1953
|
+
pc.cyan("Not logged in to thingd Cloud."),
|
|
1954
|
+
pc.dim("Press 'c' to connect to a local database, or run thingd cloud login first."),
|
|
1955
|
+
];
|
|
1956
|
+
draw();
|
|
1957
|
+
}
|
|
1977
1958
|
setupKeypress();
|
|
1978
1959
|
// Background polling loop for real-time updates
|
|
1979
1960
|
pollTimer = setInterval(async () => {
|
|
1980
|
-
if (connected
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1961
|
+
if (!connected || formState?.active || polling) {
|
|
1962
|
+
return;
|
|
1963
|
+
}
|
|
1964
|
+
polling = true;
|
|
1965
|
+
try {
|
|
1966
|
+
const snapItemId = loadedItemId;
|
|
1967
|
+
const snapshot = JSON.stringify([
|
|
1968
|
+
totalObjects,
|
|
1969
|
+
totalEventsCount,
|
|
1970
|
+
totalActiveJobsCount,
|
|
1971
|
+
totalDeadJobsCount,
|
|
1972
|
+
totalLinksCount,
|
|
1973
|
+
]);
|
|
1974
|
+
await fetchResources();
|
|
1975
|
+
const changed = snapshot !==
|
|
1976
|
+
JSON.stringify([
|
|
1977
|
+
totalObjects,
|
|
1978
|
+
totalEventsCount,
|
|
1979
|
+
totalActiveJobsCount,
|
|
1980
|
+
totalDeadJobsCount,
|
|
1981
|
+
totalLinksCount,
|
|
1982
|
+
]);
|
|
1983
|
+
const tree = buildTree();
|
|
1984
|
+
const n = tree[cursorIndex];
|
|
1985
|
+
if (n && snapItemId === n.id && n.type !== "category") {
|
|
1986
|
+
await loadContent(n).catch(() => { });
|
|
1991
1987
|
}
|
|
1992
|
-
|
|
1993
|
-
|
|
1988
|
+
if (changed) {
|
|
1989
|
+
draw();
|
|
1994
1990
|
}
|
|
1995
1991
|
}
|
|
1992
|
+
catch {
|
|
1993
|
+
// Prevent unhandled rejection from killing the process
|
|
1994
|
+
}
|
|
1995
|
+
finally {
|
|
1996
|
+
polling = false;
|
|
1997
|
+
}
|
|
1996
1998
|
}, 10_000);
|
|
1997
1999
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thingd/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.53.1",
|
|
4
4
|
"description": "CLI, Interactive TUI Dashboard, and MCP server for thingd — a fast object-first data engine for applications and AI agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://engine.thingd.cloud",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"cli-table3": "^0.6.5",
|
|
46
46
|
"picocolors": "^1.1.1",
|
|
47
47
|
"zod": "^4.4.3",
|
|
48
|
-
"@thingd/sdk": "0.
|
|
48
|
+
"@thingd/sdk": "0.53.1"
|
|
49
49
|
},
|
|
50
50
|
"engines": {
|
|
51
51
|
"node": ">=24.0.0"
|