@noy-db/in-devtools-tui 0.4.0-pre.0 → 0.4.0-pre.10
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/README.md +2 -2
- package/dist/bin.js +12 -12
- package/dist/bin.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -14,13 +14,13 @@ pnpm add -D @noy-db/in-devtools-tui
|
|
|
14
14
|
|
|
15
15
|
## Usage
|
|
16
16
|
|
|
17
|
-
Point the `noydb-inspect` bin at a config file that default-exports your `NoydbOptions`. It unlocks the vault (prompting for the
|
|
17
|
+
Point the `noydb-inspect` bin at a config file that default-exports your `NoydbOptions`. It unlocks the vault (prompting for the secret, or reading `--secret=…` / `NOYDB_SECRET`), then opens a read-only terminal dashboard of collections, records, and live writes.
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
20
|
npx noydb-inspect ./noydb.config.mjs --vault=acme
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
Add `--meter` to wrap the store in [`@noy-db/to-meter`](https://www.npmjs.com/package/@noy-db/to-meter) and show live store metrics. Like the inspector core it wraps, the TUI is read-only and never persists your
|
|
23
|
+
Add `--meter` to wrap the store in [`@noy-db/to-meter`](https://www.npmjs.com/package/@noy-db/to-meter) and show live store metrics. Like the inspector core it wraps, the TUI is read-only and never persists your secret.
|
|
24
24
|
|
|
25
25
|
## Documentation
|
|
26
26
|
|
package/dist/bin.js
CHANGED
|
@@ -380,14 +380,14 @@ async function loadOptionsFromFile(filePath) {
|
|
|
380
380
|
const value = mod.default ?? mod;
|
|
381
381
|
return typeof value === "function" ? await value() : value;
|
|
382
382
|
}
|
|
383
|
-
function
|
|
384
|
-
const flag = argv.find((a) => a.startsWith("--
|
|
385
|
-
if (flag) return flag.slice("--
|
|
386
|
-
if (env.
|
|
383
|
+
function resolveSecret(argv, env) {
|
|
384
|
+
const flag = argv.find((a) => a.startsWith("--secret="));
|
|
385
|
+
if (flag) return flag.slice("--secret=".length);
|
|
386
|
+
if (env.NOYDB_SECRET) return env.NOYDB_SECRET;
|
|
387
387
|
return void 0;
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
-
// src/prompt-
|
|
390
|
+
// src/prompt-secret.ts
|
|
391
391
|
function promptMasked(question, streams = {}) {
|
|
392
392
|
const input = streams.input ?? process.stdin;
|
|
393
393
|
const output = streams.output ?? process.stdout;
|
|
@@ -437,14 +437,14 @@ function fail(msg) {
|
|
|
437
437
|
async function main() {
|
|
438
438
|
const argv = process.argv.slice(2);
|
|
439
439
|
const configPath = argv.find((a) => !a.startsWith("--"));
|
|
440
|
-
if (!configPath) fail("usage: noydb-inspect <config.js|mjs> --vault=<name> [--
|
|
440
|
+
if (!configPath) fail("usage: noydb-inspect <config.js|mjs> --vault=<name> [--secret=\u2026]");
|
|
441
441
|
const vaultFlag = argv.find((a) => a.startsWith("--vault="));
|
|
442
442
|
if (!vaultFlag) fail("missing --vault=<name>");
|
|
443
443
|
const vaultName = vaultFlag.slice("--vault=".length);
|
|
444
|
-
let
|
|
445
|
-
if (
|
|
446
|
-
if (!process.stdin.isTTY) fail("no
|
|
447
|
-
|
|
444
|
+
let secret = resolveSecret(argv, process.env);
|
|
445
|
+
if (secret === void 0) {
|
|
446
|
+
if (!process.stdin.isTTY) fail("no secret \u2014 pass --secret=\u2026 or set NOYDB_SECRET");
|
|
447
|
+
secret = await promptMasked("Secret: ");
|
|
448
448
|
}
|
|
449
449
|
let baseOptions;
|
|
450
450
|
try {
|
|
@@ -455,10 +455,10 @@ async function main() {
|
|
|
455
455
|
let meter;
|
|
456
456
|
if (argv.includes("--meter") && baseOptions.store) {
|
|
457
457
|
const metered = toMeter(baseOptions.store);
|
|
458
|
-
baseOptions = { ...baseOptions, store: metered
|
|
458
|
+
baseOptions = { ...baseOptions, store: metered };
|
|
459
459
|
meter = metered.meter;
|
|
460
460
|
}
|
|
461
|
-
const options = { ...baseOptions, secret
|
|
461
|
+
const options = { ...baseOptions, secret };
|
|
462
462
|
const db = await createNoydb(options);
|
|
463
463
|
let vault;
|
|
464
464
|
try {
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bin.tsx","../src/App.tsx","../src/panes/VaultList.tsx","../src/panes/CollectionList.tsx","../src/panes/DetailPane.tsx","../src/panes/RecordsPane.tsx","../src/panes/WriteMonitor.tsx","../src/load-options.ts","../src/prompt-passphrase.ts"],"sourcesContent":["import React from 'react'\nimport { render } from 'ink'\nimport { createInspector } from '@noy-db/in-devtools'\nimport { createNoydb } from '@noy-db/hub'\nimport type { NoydbOptions } from '@noy-db/hub'\nimport { toMeter } from '@noy-db/to-meter'\nimport { App } from './App.js'\nimport { loadOptionsFromFile, resolvePassphrase } from './load-options.js'\nimport { promptMasked } from './prompt-passphrase.js'\n\nfunction fail(msg: string): never {\n process.stderr.write(`noydb-inspect: ${msg}\\n`)\n process.exit(2)\n}\n\nasync function main(): Promise<void> {\n const argv = process.argv.slice(2)\n const configPath = argv.find((a) => !a.startsWith('--'))\n if (!configPath) fail('usage: noydb-inspect <config.js|mjs> --vault=<name> [--passphrase=…]')\n const vaultFlag = argv.find((a) => a.startsWith('--vault='))\n if (!vaultFlag) fail('missing --vault=<name>')\n const vaultName = vaultFlag.slice('--vault='.length)\n\n let passphrase = resolvePassphrase(argv, process.env)\n if (passphrase === undefined) {\n if (!process.stdin.isTTY) fail('no passphrase — pass --passphrase=… or set NOYDB_PASSPHRASE')\n passphrase = await promptMasked('Passphrase: ')\n }\n\n let baseOptions: NoydbOptions\n try {\n baseOptions = (await loadOptionsFromFile(configPath)) as NoydbOptions\n } catch (err) {\n fail(`failed to load config \"${configPath}\": ${err instanceof Error ? err.message : String(err)}`)\n }\n\n let meter\n if (argv.includes('--meter') && baseOptions.store) {\n const metered = toMeter(baseOptions.store)\n baseOptions = { ...baseOptions, store: metered.store }\n meter = metered.meter\n }\n\n // Passphrase lives in NoydbOptions.secret — openVault(name) picks it up internally.\n const options: NoydbOptions = { ...baseOptions, secret: passphrase }\n const db = await createNoydb(options)\n\n let vault\n try {\n vault = await db.openVault(vaultName)\n } catch (err) {\n fail(`failed to open vault \"${vaultName}\": ${err instanceof Error ? err.message : String(err)}`)\n }\n\n const inspector = createInspector(db, meter ? { meter } : undefined)\n const initial = { vaults: await inspector.listVaults(), snapshot: await inspector.snapshot(vault) }\n const { waitUntilExit } = render(\n <App inspector={inspector} vault={vault} vaultName={vaultName} initial={initial} />,\n )\n await waitUntilExit()\n}\n\nmain().catch((err) => fail(err instanceof Error ? err.message : String(err)))\n","import React, { useState, useEffect } from 'react'\nimport { Box, Text, useApp, useInput } from 'ink'\nimport type { AppProps, DetailTab, View, FeedRow } from './types.js'\nimport type { RecordPage } from '@noy-db/in-devtools'\nimport type { InspectorWriteEvent } from '@noy-db/in-devtools'\nimport type { MeterSnapshot } from '@noy-db/to-meter'\nimport { VaultList } from './panes/VaultList.js'\nimport { CollectionList } from './panes/CollectionList.js'\nimport { DetailPane } from './panes/DetailPane.js'\nimport { RecordsPane } from './panes/RecordsPane.js'\nimport { WriteMonitor } from './panes/WriteMonitor.js'\n\nconst PAGE = 20\nconst BUFFER = 200\n\nfunction fmtTime(ts: number): string { return new Date(ts).toTimeString().slice(0, 8) }\n\nfunction rowOf(e: InspectorWriteEvent): FeedRow {\n const op = e.op === 'delete' ? 'del' : 'put'\n const versions = e.op === 'delete' ? `${e.baseVersion}→·` : `${e.baseVersion}→${e.version}`\n return { time: fmtTime(e.timestamp), user: e.userId, op, target: `${e.collection}/${e.docId}`, versions, baseKey: `${e.collection}/${e.docId}@${e.baseVersion}`, conflict: false }\n}\n\nexport function App({ inspector, vault, vaultName, initial }: AppProps) {\n const { exit } = useApp()\n const vaults = initial?.vaults ?? []\n const snapshot = initial?.snapshot\n const collections = snapshot?.collections ?? []\n const [selectedIdx, setSelectedIdx] = useState(0)\n const [drilled, setDrilled] = useState(false)\n const [tab, setTab] = useState<DetailTab>('schema')\n const [offset, setOffset] = useState(0)\n const [page, setPage] = useState<RecordPage | null>(null)\n const [recErr, setRecErr] = useState<string | undefined>(undefined)\n const [revealAll, setRevealAll] = useState(false)\n const current = collections[selectedIdx]\n\n // Reset reveal-all when the viewed collection changes so PII doesn't linger.\n useEffect(() => {\n setRevealAll(false)\n }, [selectedIdx])\n\n const [view, setView] = useState<View>('structure')\n const [feed, setFeed] = useState<ReadonlyArray<FeedRow>>([])\n const conflictKeys = React.useRef<Set<string>>(new Set())\n const [started, setStarted] = useState(false)\n const [meter, setMeter] = useState<MeterSnapshot | null>(null)\n useEffect(() => {\n if (view !== 'monitor') return\n const tick = () => setMeter(inspector.meterSnapshot())\n tick()\n const id = setInterval(tick, 1000)\n return () => clearInterval(id)\n }, [view, inspector])\n\n useEffect(() => {\n if (!drilled || tab !== 'records' || !current) return\n let live = true\n setPage(null); setRecErr(undefined)\n inspector.records(vault, current.name, { limit: PAGE, offset })\n .then((p) => { if (live) setPage(p) })\n .catch((e) => { if (live) setRecErr(e instanceof Error ? e.message : String(e)) })\n return () => { live = false }\n }, [drilled, tab, current, offset, inspector, vault])\n\n useEffect(() => {\n if (!started) return\n const offW = inspector.subscribe((e) => {\n setFeed((prev) => {\n const row = rowOf(e)\n if (conflictKeys.current.has(row.baseKey)) row.conflict = true\n const overlap = prev.some((r) => r.baseKey === row.baseKey && r.user !== row.user)\n if (overlap) row.conflict = true\n const next = [row, ...prev.map((r) => (r.baseKey === row.baseKey && r.user !== row.user ? { ...r, conflict: true } : r))]\n return next.slice(0, BUFFER)\n })\n })\n const offC = inspector.subscribeConflicts((c) => {\n const key = `${c.collection}/${c.docId}@${c.baseVersion}`\n conflictKeys.current.add(key)\n setFeed((prev) => prev.map((r) => (r.baseKey === key ? { ...r, conflict: true } : r)))\n })\n return () => { offW(); offC() }\n }, [started, inspector])\n\n useInput((input, key) => {\n if (input === 'q' || (key.ctrl && input === 'c')) { exit(); return }\n if (view === 'monitor') {\n if (key.escape) setView('structure')\n if (input === 'c') setFeed([])\n return\n }\n if (input === 'w') { setView('monitor'); setStarted(true); return }\n if (!drilled) {\n if (key.downArrow) setSelectedIdx((i) => Math.min(collections.length - 1, i + 1))\n if (key.upArrow) setSelectedIdx((i) => Math.max(0, i - 1))\n if (key.return) { setDrilled(true); setTab('schema') }\n return\n }\n if (key.escape) { setDrilled(false); setTab('schema'); setOffset(0) }\n if (key.tab) { setTab((t) => (t === 'schema' ? 'records' : 'schema')); setOffset(0) }\n if (tab === 'records') {\n if (input === 'n' && (!page || offset + PAGE < page.total)) setOffset((o) => o + PAGE)\n if (input === 'p' && offset - PAGE >= 0) setOffset((o) => o - PAGE)\n if (input === 'r') setRevealAll((v) => !v)\n }\n })\n\n if (view === 'monitor') return <WriteMonitor vaultName={vaultName} rows={feed} meter={meter} />\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>noy-db inspector — {vaultName} <Text dimColor>(↑/↓ · ↵ drill · ⇥ tab · q quit)</Text></Text>\n <Box marginTop={1}>\n <VaultList vaults={vaults} activeName={vaultName} {...(snapshot !== undefined ? { snapshot } : {})} />\n <CollectionList snapshot={snapshot ?? { vault: vaultName, collections: [] }} selectedIdx={selectedIdx} />\n {drilled && tab === 'records' && current\n ? <RecordsPane collection={current} page={page} revealAll={revealAll} {...(recErr !== undefined ? { error: recErr } : {})} />\n : <DetailPane collection={drilled ? current : undefined} />}\n </Box>\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport type { VaultInfo, InspectorSnapshot } from '@noy-db/in-devtools'\n\nexport function VaultList({\n vaults,\n activeName,\n snapshot,\n}: {\n vaults: ReadonlyArray<VaultInfo>\n activeName: string\n /** Active vault snapshot; used to read vault meta.label when available. */\n snapshot?: InspectorSnapshot\n}) {\n return (\n <Box flexDirection=\"column\" marginRight={2}>\n <Text bold underline>Vaults</Text>\n {vaults.map((v) => {\n // Show meta.label for the active vault when available\n const vaultLabel = v.id === activeName && snapshot?.meta?.label\n ? `${snapshot.meta.label} (${v.id})`\n : v.id\n return v.id === activeName\n ? <Text key={v.id} color=\"green\">{'› '}{vaultLabel}</Text>\n : <Text key={v.id}>{' '}{v.id}</Text>\n })}\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport type { InspectorSnapshot } from '@noy-db/in-devtools'\n\nexport function CollectionList({ snapshot, selectedIdx }: { snapshot: InspectorSnapshot; selectedIdx: number }) {\n return (\n <Box flexDirection=\"column\" marginRight={2}>\n <Text bold underline>Collections</Text>\n {snapshot.collections.map((c, i) => {\n // Show meta.label when present; append the collection key in dimmed parens\n const display = c.meta?.label ? `${c.meta.label} (${c.name})` : c.name\n return i === selectedIdx\n ? <Text key={c.name} color=\"cyan\" inverse>{display}</Text>\n : <Text key={c.name}>{display}</Text>\n })}\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport type { InspectorCollection } from '@noy-db/in-devtools'\nimport type { CollectionConfig } from '@noy-db/hub'\n\n/** Compact sensitivity marker for terminal rendering. */\nfunction sensitivityTag(s: 'public' | 'pii' | 'secret' | undefined): string {\n if (s === 'pii') return '[pii]'\n if (s === 'secret') return '[secret]'\n return ''\n}\n\n/** Render a compact config line from CollectionConfig fields that are set. */\nfunction ConfigLine({ config }: { config: CollectionConfig }) {\n const parts: string[] = []\n if (config.textIndexes?.length) parts.push(`idx:${config.textIndexes.length}`)\n if (config.embeddings) parts.push(`emb:${config.embeddings.dim}d`)\n if (config.i18nFields?.length) parts.push(`i18n:${config.i18nFields.length}`)\n if (config.crdt) parts.push(`crdt:${config.crdt}`)\n if (config.provenance) parts.push('provenance')\n if (config.archive) parts.push('archive')\n if (config.tiers?.length) parts.push(`tiers:${config.tiers.join(',')}`)\n if (config.perRecordKeys) parts.push('per-record-cek')\n if (!parts.length) return null\n return <Text dimColor>config: {parts.join(' ')}</Text>\n}\n\nexport function DetailPane({ collection }: { collection: InspectorCollection | undefined }) {\n if (!collection) return (\n <Box flexDirection=\"column\"><Text dimColor>Select a collection (↵)</Text></Box>\n )\n\n const heading = collection.meta?.label\n ? `${collection.meta.label} (${collection.name})`\n : collection.name\n\n return (\n <Box flexDirection=\"column\">\n <Text bold underline>{heading}</Text>\n {collection.meta?.description\n ? <Text dimColor>{collection.meta.description}</Text>\n : null}\n <Text>records: {collection.stats?.records ?? '—'} bytes: {collection.stats?.bytes ?? '—'}</Text>\n\n {/* Rich field list from describe() when available */}\n {collection.described && collection.described.length > 0\n ? (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>schema</Text>\n {collection.described.map((f) => {\n const sens = sensitivityTag(f.sensitivity)\n const i18nMark = f.i18n ? '[i18n]' : ''\n const roMark = f.editable === false ? '[ro]' : ''\n const widgetMark = f.widget ? `<${f.widget}>` : ''\n const markers = [sens, i18nMark, roMark, widgetMark].filter(Boolean).join(' ')\n return (\n <Text key={f.key}>\n {' '}{f.label} <Text dimColor>({f.key}: {f.type})</Text>\n {markers ? <Text color=\"yellow\"> {markers}</Text> : null}\n </Text>\n )\n })}\n </Box>\n )\n : (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>schema</Text>\n {Object.keys(collection.fields).length\n ? Object.entries(collection.fields).map(([k, f]) => (\n <Text key={k}>{' '}{k}: <Text dimColor>{f.type}</Text></Text>\n ))\n : <Text dimColor> (no declared fields)</Text>}\n </Box>\n )}\n\n {/* Collection config strip */}\n {collection.config\n ? <Box marginTop={1}><ConfigLine config={collection.config} /></Box>\n : null}\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport type { RecordPage, InspectorCollection } from '@noy-db/in-devtools'\n\nconst MASK = '••••'\n\nfunction cell(value: unknown): string {\n if (value === null || value === undefined) return '·'\n if (typeof value === 'object') return Array.isArray(value) ? `[${(value as unknown[]).length}]` : '{…}'\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') return String(value)\n return '?'\n}\n\nexport function RecordsPane({ collection, page, error, revealAll }: {\n collection: InspectorCollection\n page: RecordPage | null\n error?: string\n revealAll?: boolean\n}) {\n // Build the set of sensitive field keys from described[] (pii + secret); empty if no described.\n const sensitiveKeys: ReadonlySet<string> = React.useMemo(() => {\n if (!collection.described) return new Set<string>()\n const keys = new Set<string>()\n for (const f of collection.described) {\n if (f.sensitivity !== undefined && f.sensitivity !== 'public') keys.add(f.key)\n }\n return keys\n }, [collection.described])\n\n const schemaFields = Object.keys(collection.fields)\n if (error) return <Box flexDirection=\"column\"><Text color=\"red\">records error: {error}</Text><Text dimColor>n/p retry · ⇥ back</Text></Box>\n if (!page) return <Box flexDirection=\"column\"><Text dimColor>loading records…</Text></Box>\n // Fall back to first-row keys when schema has no declared fields\n const firstRowKeys = page.rows.length > 0 && typeof page.rows[0] === 'object' && page.rows[0] !== null\n ? Object.keys(page.rows[0] as Record<string, unknown>)\n : []\n const fields = schemaFields.length > 0 ? schemaFields : firstRowKeys\n const from = page.total === 0 ? 0 : page.offset + 1\n const to = Math.min(page.offset + page.limit, page.total)\n\n function renderCell(f: string, row: unknown): string {\n const raw = cell((row as Record<string, unknown>)?.[f])\n if (!revealAll && sensitiveKeys.has(f)) return MASK\n return raw\n }\n\n const revealHint = sensitiveKeys.size > 0 ? ' · r reveal/hide' : ''\n return (\n <Box flexDirection=\"column\">\n <Text bold>rows {from}–{to} of {page.total} <Text dimColor>(n/p page · ⇥ back{revealHint})</Text></Text>\n <Text dimColor>{fields.join(' ')}</Text>\n {page.rows.map((row, i) => (\n <Text key={i}>{fields.map((f) => renderCell(f, row)).join(' ')}</Text>\n ))}\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport type { FeedRow } from '../types.js'\nimport type { MeterSnapshot } from '@noy-db/to-meter'\n\nexport function WriteMonitor({ vaultName, rows, meter }: { vaultName: string; rows: ReadonlyArray<FeedRow>; meter: MeterSnapshot | null }) {\n const m = meter?.byMethod\n return (\n <Box flexDirection=\"column\">\n <Text bold>Write Monitor — {vaultName} <Text dimColor>(w/esc · c clear · q quit)</Text></Text>\n {meter && m && (\n <Text>\n store put p50 {m.put?.p50 ?? '—'}ms p99 {m.put?.p99 ?? '—'}ms{meter.status === 'degraded' ? ' ⚠degraded' : ''} · del p50 {m.delete?.p50 ?? '—'} p99 {m.delete?.p99 ?? '—'} · get p50 {m.get?.p50 ?? '—'} p99 {m.get?.p99 ?? '—'}\n </Text>\n )}\n <Text dimColor>time user op collection/docId v</Text>\n {rows.length === 0 && <Text dimColor>(waiting for writes…)</Text>}\n {rows.map((r, i) => (\n r.conflict\n ? <Text key={i} color=\"yellow\">{r.time} {r.user.padEnd(6)} {r.op} {r.target.padEnd(18)} {r.versions} ⚠ CONFLICT</Text>\n : <Text key={i}>{r.time} {r.user.padEnd(6)} {r.op} {r.target.padEnd(18)} {r.versions}</Text>\n ))}\n </Box>\n )\n}\n","import { resolve as resolvePath } from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\n/**\n * Load a NoydbOptions object from a `.js`/`.mjs` config (default export, or a\n * factory function). Mirrors @noy-db/cli's loader; reimplemented here to avoid\n * coupling the TUI bin to the whole cli package. `.ts` is unsupported (Node has\n * no native loader) — compile first or use a `.mjs` config.\n */\nexport async function loadOptionsFromFile(filePath: string): Promise<unknown> {\n const abs = resolvePath(filePath)\n if (/\\.[mc]?ts$/.test(abs)) {\n throw new Error(\n `TypeScript config files are not directly loadable. Compile it first, or use a .mjs/.js config.`,\n )\n }\n const mod = (await import(pathToFileURL(abs).href)) as { default?: unknown }\n const value = mod.default ?? mod\n return typeof value === 'function' ? await (value as () => Promise<unknown>)() : value\n}\n\n/** Resolve the passphrase from `--passphrase=…` or `NOYDB_PASSPHRASE`; undefined → caller prompts. */\nexport function resolvePassphrase(argv: readonly string[], env: NodeJS.ProcessEnv): string | undefined {\n const flag = argv.find((a) => a.startsWith('--passphrase='))\n if (flag) return flag.slice('--passphrase='.length)\n if (env.NOYDB_PASSPHRASE) return env.NOYDB_PASSPHRASE\n return undefined\n}\n","import type { Readable, Writable } from 'node:stream'\n\nexport interface PromptStreams {\n input?: Readable & { setRawMode?: (mode: boolean) => void }\n output?: Writable\n}\n\n/**\n * Read a line from `input` without echoing the plaintext; emit one `•` per\n * character to `output`. Returns the typed string (Enter terminates).\n * Never logs/persists the value.\n */\nexport function promptMasked(question: string, streams: PromptStreams = {}): Promise<string> {\n const input = (streams.input ?? process.stdin) as Readable & { setRawMode?: (m: boolean) => void }\n const output = streams.output ?? process.stdout\n return new Promise<string>((resolve, reject) => {\n output.write(question)\n input.setRawMode?.(true)\n let buf = ''\n const onData = (chunk: Buffer | string) => {\n const s = chunk.toString()\n for (const ch of s) {\n if (ch === '\\r' || ch === '\\n') {\n output.write('\\n')\n input.setRawMode?.(false)\n input.removeListener('data', onData)\n resolve(buf)\n return\n }\n if (ch === '\\x03') { // Ctrl-C — abort\n output.write('\\n')\n input.setRawMode?.(false)\n input.removeListener('data', onData)\n reject(new Error('aborted'))\n return\n }\n if (ch === '\\x7f' || ch === '\\x08') { // DEL / Backspace\n if (buf.length > 0) { buf = buf.slice(0, -1); output.write('\\b \\b') }\n continue\n }\n buf += ch\n output.write('•')\n }\n }\n input.on('data', onData)\n })\n}\n"],"mappings":"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","names":["React","Box","Text","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","jsx","jsxs","React","Box","Text","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/bin.tsx","../src/App.tsx","../src/panes/VaultList.tsx","../src/panes/CollectionList.tsx","../src/panes/DetailPane.tsx","../src/panes/RecordsPane.tsx","../src/panes/WriteMonitor.tsx","../src/load-options.ts","../src/prompt-secret.ts"],"sourcesContent":["import React from 'react'\nimport { render } from 'ink'\nimport { createInspector } from '@noy-db/in-devtools'\nimport { createNoydb } from '@noy-db/hub'\nimport type { NoydbOptions } from '@noy-db/hub'\nimport { toMeter } from '@noy-db/to-meter'\nimport { App } from './App.js'\nimport { loadOptionsFromFile, resolveSecret } from './load-options.js'\nimport { promptMasked } from './prompt-secret.js'\n\nfunction fail(msg: string): never {\n process.stderr.write(`noydb-inspect: ${msg}\\n`)\n process.exit(2)\n}\n\nasync function main(): Promise<void> {\n const argv = process.argv.slice(2)\n const configPath = argv.find((a) => !a.startsWith('--'))\n if (!configPath) fail('usage: noydb-inspect <config.js|mjs> --vault=<name> [--secret=…]')\n const vaultFlag = argv.find((a) => a.startsWith('--vault='))\n if (!vaultFlag) fail('missing --vault=<name>')\n const vaultName = vaultFlag.slice('--vault='.length)\n\n let secret = resolveSecret(argv, process.env)\n if (secret === undefined) {\n if (!process.stdin.isTTY) fail('no secret — pass --secret=… or set NOYDB_SECRET')\n secret = await promptMasked('Secret: ')\n }\n\n let baseOptions: NoydbOptions\n try {\n baseOptions = (await loadOptionsFromFile(configPath)) as NoydbOptions\n } catch (err) {\n fail(`failed to load config \"${configPath}\": ${err instanceof Error ? err.message : String(err)}`)\n }\n\n let meter\n if (argv.includes('--meter') && baseOptions.store) {\n // #845 — toMeter returns the store itself, with the handle attached.\n const metered = toMeter(baseOptions.store)\n baseOptions = { ...baseOptions, store: metered }\n meter = metered.meter\n }\n\n // Secret lives in NoydbOptions.secret — openVault(name) picks it up internally.\n const options: NoydbOptions = { ...baseOptions, secret: secret }\n const db = await createNoydb(options)\n\n let vault\n try {\n vault = await db.openVault(vaultName)\n } catch (err) {\n fail(`failed to open vault \"${vaultName}\": ${err instanceof Error ? err.message : String(err)}`)\n }\n\n const inspector = createInspector(db, meter ? { meter } : undefined)\n const initial = { vaults: await inspector.listVaults(), snapshot: await inspector.snapshot(vault) }\n const { waitUntilExit } = render(\n <App inspector={inspector} vault={vault} vaultName={vaultName} initial={initial} />,\n )\n await waitUntilExit()\n}\n\nmain().catch((err) => fail(err instanceof Error ? err.message : String(err)))\n","import React, { useState, useEffect } from 'react'\nimport { Box, Text, useApp, useInput } from 'ink'\nimport type { AppProps, DetailTab, View, FeedRow } from './types.js'\nimport type { RecordPage } from '@noy-db/in-devtools'\nimport type { InspectorWriteEvent } from '@noy-db/in-devtools'\nimport type { MeterSnapshot } from '@noy-db/to-meter'\nimport { VaultList } from './panes/VaultList.js'\nimport { CollectionList } from './panes/CollectionList.js'\nimport { DetailPane } from './panes/DetailPane.js'\nimport { RecordsPane } from './panes/RecordsPane.js'\nimport { WriteMonitor } from './panes/WriteMonitor.js'\n\nconst PAGE = 20\nconst BUFFER = 200\n\nfunction fmtTime(ts: number): string { return new Date(ts).toTimeString().slice(0, 8) }\n\nfunction rowOf(e: InspectorWriteEvent): FeedRow {\n const op = e.op === 'delete' ? 'del' : 'put'\n const versions = e.op === 'delete' ? `${e.baseVersion}→·` : `${e.baseVersion}→${e.version}`\n return { time: fmtTime(e.timestamp), user: e.userId, op, target: `${e.collection}/${e.docId}`, versions, baseKey: `${e.collection}/${e.docId}@${e.baseVersion}`, conflict: false }\n}\n\nexport function App({ inspector, vault, vaultName, initial }: AppProps) {\n const { exit } = useApp()\n const vaults = initial?.vaults ?? []\n const snapshot = initial?.snapshot\n const collections = snapshot?.collections ?? []\n const [selectedIdx, setSelectedIdx] = useState(0)\n const [drilled, setDrilled] = useState(false)\n const [tab, setTab] = useState<DetailTab>('schema')\n const [offset, setOffset] = useState(0)\n const [page, setPage] = useState<RecordPage | null>(null)\n const [recErr, setRecErr] = useState<string | undefined>(undefined)\n const [revealAll, setRevealAll] = useState(false)\n const current = collections[selectedIdx]\n\n // Reset reveal-all when the viewed collection changes so PII doesn't linger.\n useEffect(() => {\n setRevealAll(false)\n }, [selectedIdx])\n\n const [view, setView] = useState<View>('structure')\n const [feed, setFeed] = useState<ReadonlyArray<FeedRow>>([])\n const conflictKeys = React.useRef<Set<string>>(new Set())\n const [started, setStarted] = useState(false)\n const [meter, setMeter] = useState<MeterSnapshot | null>(null)\n useEffect(() => {\n if (view !== 'monitor') return\n const tick = () => setMeter(inspector.meterSnapshot())\n tick()\n const id = setInterval(tick, 1000)\n return () => clearInterval(id)\n }, [view, inspector])\n\n useEffect(() => {\n if (!drilled || tab !== 'records' || !current) return\n let live = true\n setPage(null); setRecErr(undefined)\n inspector.records(vault, current.name, { limit: PAGE, offset })\n .then((p) => { if (live) setPage(p) })\n .catch((e) => { if (live) setRecErr(e instanceof Error ? e.message : String(e)) })\n return () => { live = false }\n }, [drilled, tab, current, offset, inspector, vault])\n\n useEffect(() => {\n if (!started) return\n const offW = inspector.subscribe((e) => {\n setFeed((prev) => {\n const row = rowOf(e)\n if (conflictKeys.current.has(row.baseKey)) row.conflict = true\n const overlap = prev.some((r) => r.baseKey === row.baseKey && r.user !== row.user)\n if (overlap) row.conflict = true\n const next = [row, ...prev.map((r) => (r.baseKey === row.baseKey && r.user !== row.user ? { ...r, conflict: true } : r))]\n return next.slice(0, BUFFER)\n })\n })\n const offC = inspector.subscribeConflicts((c) => {\n const key = `${c.collection}/${c.docId}@${c.baseVersion}`\n conflictKeys.current.add(key)\n setFeed((prev) => prev.map((r) => (r.baseKey === key ? { ...r, conflict: true } : r)))\n })\n return () => { offW(); offC() }\n }, [started, inspector])\n\n useInput((input, key) => {\n if (input === 'q' || (key.ctrl && input === 'c')) { exit(); return }\n if (view === 'monitor') {\n if (key.escape) setView('structure')\n if (input === 'c') setFeed([])\n return\n }\n if (input === 'w') { setView('monitor'); setStarted(true); return }\n if (!drilled) {\n if (key.downArrow) setSelectedIdx((i) => Math.min(collections.length - 1, i + 1))\n if (key.upArrow) setSelectedIdx((i) => Math.max(0, i - 1))\n if (key.return) { setDrilled(true); setTab('schema') }\n return\n }\n if (key.escape) { setDrilled(false); setTab('schema'); setOffset(0) }\n if (key.tab) { setTab((t) => (t === 'schema' ? 'records' : 'schema')); setOffset(0) }\n if (tab === 'records') {\n if (input === 'n' && (!page || offset + PAGE < page.total)) setOffset((o) => o + PAGE)\n if (input === 'p' && offset - PAGE >= 0) setOffset((o) => o - PAGE)\n if (input === 'r') setRevealAll((v) => !v)\n }\n })\n\n if (view === 'monitor') return <WriteMonitor vaultName={vaultName} rows={feed} meter={meter} />\n\n return (\n <Box flexDirection=\"column\">\n <Text bold>noy-db inspector — {vaultName} <Text dimColor>(↑/↓ · ↵ drill · ⇥ tab · q quit)</Text></Text>\n <Box marginTop={1}>\n <VaultList vaults={vaults} activeName={vaultName} {...(snapshot !== undefined ? { snapshot } : {})} />\n <CollectionList snapshot={snapshot ?? { vault: vaultName, collections: [] }} selectedIdx={selectedIdx} />\n {drilled && tab === 'records' && current\n ? <RecordsPane collection={current} page={page} revealAll={revealAll} {...(recErr !== undefined ? { error: recErr } : {})} />\n : <DetailPane collection={drilled ? current : undefined} />}\n </Box>\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport type { VaultInfo, InspectorSnapshot } from '@noy-db/in-devtools'\n\nexport function VaultList({\n vaults,\n activeName,\n snapshot,\n}: {\n vaults: ReadonlyArray<VaultInfo>\n activeName: string\n /** Active vault snapshot; used to read vault meta.label when available. */\n snapshot?: InspectorSnapshot\n}) {\n return (\n <Box flexDirection=\"column\" marginRight={2}>\n <Text bold underline>Vaults</Text>\n {vaults.map((v) => {\n // Show meta.label for the active vault when available\n const vaultLabel = v.id === activeName && snapshot?.meta?.label\n ? `${snapshot.meta.label} (${v.id})`\n : v.id\n return v.id === activeName\n ? <Text key={v.id} color=\"green\">{'› '}{vaultLabel}</Text>\n : <Text key={v.id}>{' '}{v.id}</Text>\n })}\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport type { InspectorSnapshot } from '@noy-db/in-devtools'\n\nexport function CollectionList({ snapshot, selectedIdx }: { snapshot: InspectorSnapshot; selectedIdx: number }) {\n return (\n <Box flexDirection=\"column\" marginRight={2}>\n <Text bold underline>Collections</Text>\n {snapshot.collections.map((c, i) => {\n // Show meta.label when present; append the collection key in dimmed parens\n const display = c.meta?.label ? `${c.meta.label} (${c.name})` : c.name\n return i === selectedIdx\n ? <Text key={c.name} color=\"cyan\" inverse>{display}</Text>\n : <Text key={c.name}>{display}</Text>\n })}\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport type { InspectorCollection } from '@noy-db/in-devtools'\nimport type { CollectionConfig } from '@noy-db/hub'\n\n/** Compact sensitivity marker for terminal rendering. */\nfunction sensitivityTag(s: 'public' | 'pii' | 'secret' | undefined): string {\n if (s === 'pii') return '[pii]'\n if (s === 'secret') return '[secret]'\n return ''\n}\n\n/** Render a compact config line from CollectionConfig fields that are set. */\nfunction ConfigLine({ config }: { config: CollectionConfig }) {\n const parts: string[] = []\n if (config.textIndexes?.length) parts.push(`idx:${config.textIndexes.length}`)\n if (config.embeddings) parts.push(`emb:${config.embeddings.dim}d`)\n if (config.i18nFields?.length) parts.push(`i18n:${config.i18nFields.length}`)\n if (config.crdt) parts.push(`crdt:${config.crdt}`)\n if (config.provenance) parts.push('provenance')\n if (config.archive) parts.push('archive')\n if (config.tiers?.length) parts.push(`tiers:${config.tiers.join(',')}`)\n if (config.perRecordKeys) parts.push('per-record-cek')\n if (!parts.length) return null\n return <Text dimColor>config: {parts.join(' ')}</Text>\n}\n\nexport function DetailPane({ collection }: { collection: InspectorCollection | undefined }) {\n if (!collection) return (\n <Box flexDirection=\"column\"><Text dimColor>Select a collection (↵)</Text></Box>\n )\n\n const heading = collection.meta?.label\n ? `${collection.meta.label} (${collection.name})`\n : collection.name\n\n return (\n <Box flexDirection=\"column\">\n <Text bold underline>{heading}</Text>\n {collection.meta?.description\n ? <Text dimColor>{collection.meta.description}</Text>\n : null}\n <Text>records: {collection.stats?.records ?? '—'} bytes: {collection.stats?.bytes ?? '—'}</Text>\n\n {/* Rich field list from describe() when available */}\n {collection.described && collection.described.length > 0\n ? (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>schema</Text>\n {collection.described.map((f) => {\n const sens = sensitivityTag(f.sensitivity)\n const i18nMark = f.i18n ? '[i18n]' : ''\n const roMark = f.editable === false ? '[ro]' : ''\n const widgetMark = f.widget ? `<${f.widget}>` : ''\n const markers = [sens, i18nMark, roMark, widgetMark].filter(Boolean).join(' ')\n return (\n <Text key={f.key}>\n {' '}{f.label} <Text dimColor>({f.key}: {f.type})</Text>\n {markers ? <Text color=\"yellow\"> {markers}</Text> : null}\n </Text>\n )\n })}\n </Box>\n )\n : (\n <Box flexDirection=\"column\" marginTop={1}>\n <Text bold>schema</Text>\n {Object.keys(collection.fields).length\n ? Object.entries(collection.fields).map(([k, f]) => (\n <Text key={k}>{' '}{k}: <Text dimColor>{f.type}</Text></Text>\n ))\n : <Text dimColor> (no declared fields)</Text>}\n </Box>\n )}\n\n {/* Collection config strip */}\n {collection.config\n ? <Box marginTop={1}><ConfigLine config={collection.config} /></Box>\n : null}\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport type { RecordPage, InspectorCollection } from '@noy-db/in-devtools'\n\nconst MASK = '••••'\n\nfunction cell(value: unknown): string {\n if (value === null || value === undefined) return '·'\n if (typeof value === 'object') return Array.isArray(value) ? `[${(value as unknown[]).length}]` : '{…}'\n if (typeof value === 'string') return value\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') return String(value)\n return '?'\n}\n\nexport function RecordsPane({ collection, page, error, revealAll }: {\n collection: InspectorCollection\n page: RecordPage | null\n error?: string\n revealAll?: boolean\n}) {\n // Build the set of sensitive field keys from described[] (pii + secret); empty if no described.\n const sensitiveKeys: ReadonlySet<string> = React.useMemo(() => {\n if (!collection.described) return new Set<string>()\n const keys = new Set<string>()\n for (const f of collection.described) {\n if (f.sensitivity !== undefined && f.sensitivity !== 'public') keys.add(f.key)\n }\n return keys\n }, [collection.described])\n\n const schemaFields = Object.keys(collection.fields)\n if (error) return <Box flexDirection=\"column\"><Text color=\"red\">records error: {error}</Text><Text dimColor>n/p retry · ⇥ back</Text></Box>\n if (!page) return <Box flexDirection=\"column\"><Text dimColor>loading records…</Text></Box>\n // Fall back to first-row keys when schema has no declared fields\n const firstRowKeys = page.rows.length > 0 && typeof page.rows[0] === 'object' && page.rows[0] !== null\n ? Object.keys(page.rows[0] as Record<string, unknown>)\n : []\n const fields = schemaFields.length > 0 ? schemaFields : firstRowKeys\n const from = page.total === 0 ? 0 : page.offset + 1\n const to = Math.min(page.offset + page.limit, page.total)\n\n function renderCell(f: string, row: unknown): string {\n const raw = cell((row as Record<string, unknown>)?.[f])\n if (!revealAll && sensitiveKeys.has(f)) return MASK\n return raw\n }\n\n const revealHint = sensitiveKeys.size > 0 ? ' · r reveal/hide' : ''\n return (\n <Box flexDirection=\"column\">\n <Text bold>rows {from}–{to} of {page.total} <Text dimColor>(n/p page · ⇥ back{revealHint})</Text></Text>\n <Text dimColor>{fields.join(' ')}</Text>\n {page.rows.map((row, i) => (\n <Text key={i}>{fields.map((f) => renderCell(f, row)).join(' ')}</Text>\n ))}\n </Box>\n )\n}\n","import React from 'react'\nimport { Box, Text } from 'ink'\nimport type { FeedRow } from '../types.js'\nimport type { MeterSnapshot } from '@noy-db/to-meter'\n\nexport function WriteMonitor({ vaultName, rows, meter }: { vaultName: string; rows: ReadonlyArray<FeedRow>; meter: MeterSnapshot | null }) {\n const m = meter?.byMethod\n return (\n <Box flexDirection=\"column\">\n <Text bold>Write Monitor — {vaultName} <Text dimColor>(w/esc · c clear · q quit)</Text></Text>\n {meter && m && (\n <Text>\n store put p50 {m.put?.p50 ?? '—'}ms p99 {m.put?.p99 ?? '—'}ms{meter.status === 'degraded' ? ' ⚠degraded' : ''} · del p50 {m.delete?.p50 ?? '—'} p99 {m.delete?.p99 ?? '—'} · get p50 {m.get?.p50 ?? '—'} p99 {m.get?.p99 ?? '—'}\n </Text>\n )}\n <Text dimColor>time user op collection/docId v</Text>\n {rows.length === 0 && <Text dimColor>(waiting for writes…)</Text>}\n {rows.map((r, i) => (\n r.conflict\n ? <Text key={i} color=\"yellow\">{r.time} {r.user.padEnd(6)} {r.op} {r.target.padEnd(18)} {r.versions} ⚠ CONFLICT</Text>\n : <Text key={i}>{r.time} {r.user.padEnd(6)} {r.op} {r.target.padEnd(18)} {r.versions}</Text>\n ))}\n </Box>\n )\n}\n","import { resolve as resolvePath } from 'node:path'\nimport { pathToFileURL } from 'node:url'\n\n/**\n * Load a NoydbOptions object from a `.js`/`.mjs` config (default export, or a\n * factory function). Mirrors @noy-db/cli's loader; reimplemented here to avoid\n * coupling the TUI bin to the whole cli package. `.ts` is unsupported (Node has\n * no native loader) — compile first or use a `.mjs` config.\n */\nexport async function loadOptionsFromFile(filePath: string): Promise<unknown> {\n const abs = resolvePath(filePath)\n if (/\\.[mc]?ts$/.test(abs)) {\n throw new Error(\n `TypeScript config files are not directly loadable. Compile it first, or use a .mjs/.js config.`,\n )\n }\n const mod = (await import(pathToFileURL(abs).href)) as { default?: unknown }\n const value = mod.default ?? mod\n return typeof value === 'function' ? await (value as () => Promise<unknown>)() : value\n}\n\n/** Resolve the secret from `--secret=…` or `NOYDB_SECRET`; undefined → caller prompts. */\nexport function resolveSecret(argv: readonly string[], env: NodeJS.ProcessEnv): string | undefined {\n const flag = argv.find((a) => a.startsWith('--secret='))\n if (flag) return flag.slice('--secret='.length)\n if (env.NOYDB_SECRET) return env.NOYDB_SECRET\n return undefined\n}\n","import type { Readable, Writable } from 'node:stream'\n\nexport interface PromptStreams {\n input?: Readable & { setRawMode?: (mode: boolean) => void }\n output?: Writable\n}\n\n/**\n * Read a line from `input` without echoing the plaintext; emit one `•` per\n * character to `output`. Returns the typed string (Enter terminates).\n * Never logs/persists the value.\n */\nexport function promptMasked(question: string, streams: PromptStreams = {}): Promise<string> {\n const input = (streams.input ?? process.stdin) as Readable & { setRawMode?: (m: boolean) => void }\n const output = streams.output ?? process.stdout\n return new Promise<string>((resolve, reject) => {\n output.write(question)\n input.setRawMode?.(true)\n let buf = ''\n const onData = (chunk: Buffer | string) => {\n const s = chunk.toString()\n for (const ch of s) {\n if (ch === '\\r' || ch === '\\n') {\n output.write('\\n')\n input.setRawMode?.(false)\n input.removeListener('data', onData)\n resolve(buf)\n return\n }\n if (ch === '\\x03') { // Ctrl-C — abort\n output.write('\\n')\n input.setRawMode?.(false)\n input.removeListener('data', onData)\n reject(new Error('aborted'))\n return\n }\n if (ch === '\\x7f' || ch === '\\x08') { // DEL / Backspace\n if (buf.length > 0) { buf = buf.slice(0, -1); output.write('\\b \\b') }\n continue\n }\n buf += ch\n output.write('•')\n }\n }\n input.on('data', onData)\n })\n}\n"],"mappings":";;;AACA,SAAS,cAAc;AACvB,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAE5B,SAAS,eAAe;;;ACLxB,OAAOA,UAAS,UAAU,iBAAiB;AAC3C,SAAS,OAAAC,MAAK,QAAAC,OAAM,QAAQ,gBAAgB;;;ACA5C,SAAS,KAAK,YAAY;AAepB,cAOM,YAPN;AAZC,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,SACE,qBAAC,OAAI,eAAc,UAAS,aAAa,GACvC;AAAA,wBAAC,QAAK,MAAI,MAAC,WAAS,MAAC,oBAAM;AAAA,IAC1B,OAAO,IAAI,CAAC,MAAM;AAEjB,YAAM,aAAa,EAAE,OAAO,cAAc,UAAU,MAAM,QACtD,GAAG,SAAS,KAAK,KAAK,KAAK,EAAE,EAAE,MAC/B,EAAE;AACN,aAAO,EAAE,OAAO,aACZ,qBAAC,QAAgB,OAAM,SAAS;AAAA;AAAA,QAAM;AAAA,WAA3B,EAAE,EAAoC,IACjD,qBAAC,QAAiB;AAAA;AAAA,QAAM,EAAE;AAAA,WAAf,EAAE,EAAgB;AAAA,IACnC,CAAC;AAAA,KACH;AAEJ;;;AC3BA,SAAS,OAAAC,MAAK,QAAAC,aAAY;AAKtB,SACE,OAAAC,MADF,QAAAC,aAAA;AAFG,SAAS,eAAe,EAAE,UAAU,YAAY,GAAyD;AAC9G,SACE,gBAAAA,MAACH,MAAA,EAAI,eAAc,UAAS,aAAa,GACvC;AAAA,oBAAAE,KAACD,OAAA,EAAK,MAAI,MAAC,WAAS,MAAC,yBAAW;AAAA,IAC/B,SAAS,YAAY,IAAI,CAAC,GAAG,MAAM;AAElC,YAAM,UAAU,EAAE,MAAM,QAAQ,GAAG,EAAE,KAAK,KAAK,KAAK,EAAE,IAAI,MAAM,EAAE;AAClE,aAAO,MAAM,cACT,gBAAAC,KAACD,OAAA,EAAkB,OAAM,QAAO,SAAO,MAAE,qBAA9B,EAAE,IAAoC,IACjD,gBAAAC,KAACD,OAAA,EAAmB,qBAAT,EAAE,IAAe;AAAA,IAClC,CAAC;AAAA,KACH;AAEJ;;;AChBA,SAAS,OAAAG,MAAK,QAAAC,aAAY;AAuBjB,SAKuB,OAAAC,MALvB,QAAAC,aAAA;AAlBT,SAAS,eAAe,GAAoD;AAC1E,MAAI,MAAM,MAAO,QAAO;AACxB,MAAI,MAAM,SAAU,QAAO;AAC3B,SAAO;AACT;AAGA,SAAS,WAAW,EAAE,OAAO,GAAiC;AAC5D,QAAM,QAAkB,CAAC;AACzB,MAAI,OAAO,aAAa,OAAQ,OAAM,KAAK,OAAO,OAAO,YAAY,MAAM,EAAE;AAC7E,MAAI,OAAO,WAAY,OAAM,KAAK,OAAO,OAAO,WAAW,GAAG,GAAG;AACjE,MAAI,OAAO,YAAY,OAAQ,OAAM,KAAK,QAAQ,OAAO,WAAW,MAAM,EAAE;AAC5E,MAAI,OAAO,KAAM,OAAM,KAAK,QAAQ,OAAO,IAAI,EAAE;AACjD,MAAI,OAAO,WAAY,OAAM,KAAK,YAAY;AAC9C,MAAI,OAAO,QAAS,OAAM,KAAK,SAAS;AACxC,MAAI,OAAO,OAAO,OAAQ,OAAM,KAAK,SAAS,OAAO,MAAM,KAAK,GAAG,CAAC,EAAE;AACtE,MAAI,OAAO,cAAe,OAAM,KAAK,gBAAgB;AACrD,MAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,SAAO,gBAAAA,MAACF,OAAA,EAAK,UAAQ,MAAC;AAAA;AAAA,IAAS,MAAM,KAAK,IAAI;AAAA,KAAE;AAClD;AAEO,SAAS,WAAW,EAAE,WAAW,GAAoD;AAC1F,MAAI,CAAC,WAAY,QACf,gBAAAC,KAACF,MAAA,EAAI,eAAc,UAAS,0BAAAE,KAACD,OAAA,EAAK,UAAQ,MAAC,0CAAuB,GAAO;AAG3E,QAAM,UAAU,WAAW,MAAM,QAC7B,GAAG,WAAW,KAAK,KAAK,KAAK,WAAW,IAAI,MAC5C,WAAW;AAEf,SACE,gBAAAE,MAACH,MAAA,EAAI,eAAc,UACjB;AAAA,oBAAAE,KAACD,OAAA,EAAK,MAAI,MAAC,WAAS,MAAE,mBAAQ;AAAA,IAC7B,WAAW,MAAM,cACd,gBAAAC,KAACD,OAAA,EAAK,UAAQ,MAAE,qBAAW,KAAK,aAAY,IAC5C;AAAA,IACJ,gBAAAE,MAACF,OAAA,EAAK;AAAA;AAAA,MAAU,WAAW,OAAO,WAAW;AAAA,MAAI;AAAA,MAAU,WAAW,OAAO,SAAS;AAAA,OAAI;AAAA,IAGzF,WAAW,aAAa,WAAW,UAAU,SAAS,IAEnD,gBAAAE,MAACH,MAAA,EAAI,eAAc,UAAS,WAAW,GACrC;AAAA,sBAAAE,KAACD,OAAA,EAAK,MAAI,MAAC,oBAAM;AAAA,MAChB,WAAW,UAAU,IAAI,CAAC,MAAM;AAC/B,cAAM,OAAO,eAAe,EAAE,WAAW;AACzC,cAAM,WAAW,EAAE,OAAO,WAAW;AACrC,cAAM,SAAS,EAAE,aAAa,QAAQ,SAAS;AAC/C,cAAM,aAAa,EAAE,SAAS,IAAI,EAAE,MAAM,MAAM;AAChD,cAAM,UAAU,CAAC,MAAM,UAAU,QAAQ,UAAU,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAC7E,eACE,gBAAAE,MAACF,OAAA,EACE;AAAA;AAAA,UAAM,EAAE;AAAA,UAAM;AAAA,UAAC,gBAAAE,MAACF,OAAA,EAAK,UAAQ,MAAC;AAAA;AAAA,YAAE,EAAE;AAAA,YAAI;AAAA,YAAG,EAAE;AAAA,YAAK;AAAA,aAAC;AAAA,UACjD,UAAU,gBAAAE,MAACF,OAAA,EAAK,OAAM,UAAS;AAAA;AAAA,YAAG;AAAA,aAAQ,IAAU;AAAA,aAF5C,EAAE,GAGb;AAAA,MAEJ,CAAC;AAAA,OACH,IAGA,gBAAAE,MAACH,MAAA,EAAI,eAAc,UAAS,WAAW,GACrC;AAAA,sBAAAE,KAACD,OAAA,EAAK,MAAI,MAAC,oBAAM;AAAA,MAChB,OAAO,KAAK,WAAW,MAAM,EAAE,SAC5B,OAAO,QAAQ,WAAW,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAC5C,gBAAAE,MAACF,OAAA,EAAc;AAAA;AAAA,QAAM;AAAA,QAAE;AAAA,QAAE,gBAAAC,KAACD,OAAA,EAAK,UAAQ,MAAE,YAAE,MAAK;AAAA,WAArC,CAA4C,CACxD,IACC,gBAAAC,KAACD,OAAA,EAAK,UAAQ,MAAC,oCAAsB;AAAA,OAC3C;AAAA,IAIH,WAAW,SACR,gBAAAC,KAACF,MAAA,EAAI,WAAW,GAAG,0BAAAE,KAAC,cAAW,QAAQ,WAAW,QAAQ,GAAE,IAC5D;AAAA,KACN;AAEJ;;;ACjFA,OAAO,WAAW;AAClB,SAAS,OAAAE,MAAK,QAAAC,aAAY;AA8BsB,SAA+C,OAAAC,MAA/C,QAAAC,aAAA;AA3BhD,IAAM,OAAO;AAEb,SAAS,KAAK,OAAwB;AACpC,MAAI,UAAU,QAAQ,UAAU,OAAW,QAAO;AAClD,MAAI,OAAO,UAAU,SAAU,QAAO,MAAM,QAAQ,KAAK,IAAI,IAAK,MAAoB,MAAM,MAAM;AAClG,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,aAAa,OAAO,UAAU,SAAU,QAAO,OAAO,KAAK;AAC7G,SAAO;AACT;AAEO,SAAS,YAAY,EAAE,YAAY,MAAM,OAAO,UAAU,GAK9D;AAED,QAAM,gBAAqC,MAAM,QAAQ,MAAM;AAC7D,QAAI,CAAC,WAAW,UAAW,QAAO,oBAAI,IAAY;AAClD,UAAM,OAAO,oBAAI,IAAY;AAC7B,eAAW,KAAK,WAAW,WAAW;AACpC,UAAI,EAAE,gBAAgB,UAAa,EAAE,gBAAgB,SAAU,MAAK,IAAI,EAAE,GAAG;AAAA,IAC/E;AACA,WAAO;AAAA,EACT,GAAG,CAAC,WAAW,SAAS,CAAC;AAEzB,QAAM,eAAe,OAAO,KAAK,WAAW,MAAM;AAClD,MAAI,MAAO,QAAO,gBAAAA,MAACH,MAAA,EAAI,eAAc,UAAS;AAAA,oBAAAG,MAACF,OAAA,EAAK,OAAM,OAAM;AAAA;AAAA,MAAgB;AAAA,OAAM;AAAA,IAAO,gBAAAC,KAACD,OAAA,EAAK,UAAQ,MAAC,wCAAkB;AAAA,KAAO;AACrI,MAAI,CAAC,KAAM,QAAO,gBAAAC,KAACF,MAAA,EAAI,eAAc,UAAS,0BAAAE,KAACD,OAAA,EAAK,UAAQ,MAAC,mCAAgB,GAAO;AAEpF,QAAM,eAAe,KAAK,KAAK,SAAS,KAAK,OAAO,KAAK,KAAK,CAAC,MAAM,YAAY,KAAK,KAAK,CAAC,MAAM,OAC9F,OAAO,KAAK,KAAK,KAAK,CAAC,CAA4B,IACnD,CAAC;AACL,QAAM,SAAS,aAAa,SAAS,IAAI,eAAe;AACxD,QAAM,OAAO,KAAK,UAAU,IAAI,IAAI,KAAK,SAAS;AAClD,QAAM,KAAK,KAAK,IAAI,KAAK,SAAS,KAAK,OAAO,KAAK,KAAK;AAExD,WAAS,WAAW,GAAW,KAAsB;AACnD,UAAM,MAAM,KAAM,MAAkC,CAAC,CAAC;AACtD,QAAI,CAAC,aAAa,cAAc,IAAI,CAAC,EAAG,QAAO;AAC/C,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,cAAc,OAAO,IAAI,wBAAqB;AACjE,SACE,gBAAAE,MAACH,MAAA,EAAI,eAAc,UACjB;AAAA,oBAAAG,MAACF,OAAA,EAAK,MAAI,MAAC;AAAA;AAAA,MAAM;AAAA,MAAK;AAAA,MAAE;AAAA,MAAG;AAAA,MAAK,KAAK;AAAA,MAAM;AAAA,MAAC,gBAAAE,MAACF,OAAA,EAAK,UAAQ,MAAC;AAAA;AAAA,QAAmB;AAAA,QAAW;AAAA,SAAC;AAAA,OAAO;AAAA,IACjG,gBAAAC,KAACD,OAAA,EAAK,UAAQ,MAAE,iBAAO,KAAK,IAAI,GAAE;AAAA,IACjC,KAAK,KAAK,IAAI,CAAC,KAAK,MACnB,gBAAAC,KAACD,OAAA,EAAc,iBAAO,IAAI,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC,EAAE,KAAK,IAAI,KAAnD,CAAqD,CACjE;AAAA,KACH;AAEJ;;;ACxDA,SAAS,OAAAG,MAAK,QAAAC,aAAY;AAQpB,SAAuC,OAAAC,MAAvC,QAAAC,aAAA;AAJC,SAAS,aAAa,EAAE,WAAW,MAAM,MAAM,GAAqF;AACzI,QAAM,IAAI,OAAO;AACjB,SACE,gBAAAA,MAACH,MAAA,EAAI,eAAc,UACjB;AAAA,oBAAAG,MAACF,OAAA,EAAK,MAAI,MAAC;AAAA;AAAA,MAAiB;AAAA,MAAU;AAAA,MAAC,gBAAAC,KAACD,OAAA,EAAK,UAAQ,MAAC,8CAA0B;AAAA,OAAO;AAAA,IACtF,SAAS,KACR,gBAAAE,MAACF,OAAA,EAAK;AAAA;AAAA,MACY,EAAE,KAAK,OAAO;AAAA,MAAI;AAAA,MAAQ,EAAE,KAAK,OAAO;AAAA,MAAI;AAAA,MAAG,MAAM,WAAW,aAAa,oBAAe;AAAA,MAAG;AAAA,MAAY,EAAE,QAAQ,OAAO;AAAA,MAAI;AAAA,MAAM,EAAE,QAAQ,OAAO;AAAA,MAAI;AAAA,MAAY,EAAE,KAAK,OAAO;AAAA,MAAI;AAAA,MAAM,EAAE,KAAK,OAAO;AAAA,OAC/N;AAAA,IAEF,gBAAAC,KAACD,OAAA,EAAK,UAAQ,MAAC,0DAA4C;AAAA,IAC1D,KAAK,WAAW,KAAK,gBAAAC,KAACD,OAAA,EAAK,UAAQ,MAAC,wCAAqB;AAAA,IACzD,KAAK,IAAI,CAAC,GAAG,MACZ,EAAE,WACE,gBAAAE,MAACF,OAAA,EAAa,OAAM,UAAU;AAAA,QAAE;AAAA,MAAK;AAAA,MAAG,EAAE,KAAK,OAAO,CAAC;AAAA,MAAE;AAAA,MAAG,EAAE;AAAA,MAAG;AAAA,MAAG,EAAE,OAAO,OAAO,EAAE;AAAA,MAAE;AAAA,MAAE,EAAE;AAAA,MAAS;AAAA,SAA1F,CAAsG,IACjH,gBAAAE,MAACF,OAAA,EAAc;AAAA,QAAE;AAAA,MAAK;AAAA,MAAG,EAAE,KAAK,OAAO,CAAC;AAAA,MAAE;AAAA,MAAG,EAAE;AAAA,MAAG;AAAA,MAAG,EAAE,OAAO,OAAO,EAAE;AAAA,MAAE;AAAA,MAAE,EAAE;AAAA,SAAlE,CAA2E,CAC3F;AAAA,KACH;AAEJ;;;ALoFiC,gBAAAG,MAI3B,QAAAC,aAJ2B;AAhGjC,IAAM,OAAO;AACb,IAAM,SAAS;AAEf,SAAS,QAAQ,IAAoB;AAAE,SAAO,IAAI,KAAK,EAAE,EAAE,aAAa,EAAE,MAAM,GAAG,CAAC;AAAE;AAEtF,SAAS,MAAM,GAAiC;AAC9C,QAAM,KAAK,EAAE,OAAO,WAAW,QAAQ;AACvC,QAAM,WAAW,EAAE,OAAO,WAAW,GAAG,EAAE,WAAW,eAAO,GAAG,EAAE,WAAW,SAAI,EAAE,OAAO;AACzF,SAAO,EAAE,MAAM,QAAQ,EAAE,SAAS,GAAG,MAAM,EAAE,QAAQ,IAAI,QAAQ,GAAG,EAAE,UAAU,IAAI,EAAE,KAAK,IAAI,UAAU,SAAS,GAAG,EAAE,UAAU,IAAI,EAAE,KAAK,IAAI,EAAE,WAAW,IAAI,UAAU,MAAM;AACnL;AAEO,SAAS,IAAI,EAAE,WAAW,OAAO,WAAW,QAAQ,GAAa;AACtE,QAAM,EAAE,KAAK,IAAI,OAAO;AACxB,QAAM,SAAS,SAAS,UAAU,CAAC;AACnC,QAAM,WAAW,SAAS;AAC1B,QAAM,cAAc,UAAU,eAAe,CAAC;AAC9C,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,CAAC;AAChD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,KAAK,MAAM,IAAI,SAAoB,QAAQ;AAClD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,CAAC;AACtC,QAAM,CAAC,MAAM,OAAO,IAAI,SAA4B,IAAI;AACxD,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA6B,MAAS;AAClE,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,QAAM,UAAU,YAAY,WAAW;AAGvC,YAAU,MAAM;AACd,iBAAa,KAAK;AAAA,EACpB,GAAG,CAAC,WAAW,CAAC;AAEhB,QAAM,CAAC,MAAM,OAAO,IAAI,SAAe,WAAW;AAClD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAiC,CAAC,CAAC;AAC3D,QAAM,eAAeC,OAAM,OAAoB,oBAAI,IAAI,CAAC;AACxD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA+B,IAAI;AAC7D,YAAU,MAAM;AACd,QAAI,SAAS,UAAW;AACxB,UAAM,OAAO,MAAM,SAAS,UAAU,cAAc,CAAC;AACrD,SAAK;AACL,UAAM,KAAK,YAAY,MAAM,GAAI;AACjC,WAAO,MAAM,cAAc,EAAE;AAAA,EAC/B,GAAG,CAAC,MAAM,SAAS,CAAC;AAEpB,YAAU,MAAM;AACd,QAAI,CAAC,WAAW,QAAQ,aAAa,CAAC,QAAS;AAC/C,QAAI,OAAO;AACX,YAAQ,IAAI;AAAG,cAAU,MAAS;AAClC,cAAU,QAAQ,OAAO,QAAQ,MAAM,EAAE,OAAO,MAAM,OAAO,CAAC,EAC3D,KAAK,CAAC,MAAM;AAAE,UAAI,KAAM,SAAQ,CAAC;AAAA,IAAE,CAAC,EACpC,MAAM,CAAC,MAAM;AAAE,UAAI,KAAM,WAAU,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,IAAE,CAAC;AACnF,WAAO,MAAM;AAAE,aAAO;AAAA,IAAM;AAAA,EAC9B,GAAG,CAAC,SAAS,KAAK,SAAS,QAAQ,WAAW,KAAK,CAAC;AAEpD,YAAU,MAAM;AACd,QAAI,CAAC,QAAS;AACd,UAAM,OAAO,UAAU,UAAU,CAAC,MAAM;AACtC,cAAQ,CAAC,SAAS;AAChB,cAAM,MAAM,MAAM,CAAC;AACnB,YAAI,aAAa,QAAQ,IAAI,IAAI,OAAO,EAAG,KAAI,WAAW;AAC1D,cAAM,UAAU,KAAK,KAAK,CAAC,MAAM,EAAE,YAAY,IAAI,WAAW,EAAE,SAAS,IAAI,IAAI;AACjF,YAAI,QAAS,KAAI,WAAW;AAC5B,cAAM,OAAO,CAAC,KAAK,GAAG,KAAK,IAAI,CAAC,MAAO,EAAE,YAAY,IAAI,WAAW,EAAE,SAAS,IAAI,OAAO,EAAE,GAAG,GAAG,UAAU,KAAK,IAAI,CAAE,CAAC;AACxH,eAAO,KAAK,MAAM,GAAG,MAAM;AAAA,MAC7B,CAAC;AAAA,IACH,CAAC;AACD,UAAM,OAAO,UAAU,mBAAmB,CAAC,MAAM;AAC/C,YAAM,MAAM,GAAG,EAAE,UAAU,IAAI,EAAE,KAAK,IAAI,EAAE,WAAW;AACvD,mBAAa,QAAQ,IAAI,GAAG;AAC5B,cAAQ,CAAC,SAAS,KAAK,IAAI,CAAC,MAAO,EAAE,YAAY,MAAM,EAAE,GAAG,GAAG,UAAU,KAAK,IAAI,CAAE,CAAC;AAAA,IACvF,CAAC;AACD,WAAO,MAAM;AAAE,WAAK;AAAG,WAAK;AAAA,IAAE;AAAA,EAChC,GAAG,CAAC,SAAS,SAAS,CAAC;AAEvB,WAAS,CAAC,OAAO,QAAQ;AACvB,QAAI,UAAU,OAAQ,IAAI,QAAQ,UAAU,KAAM;AAAE,WAAK;AAAG;AAAA,IAAO;AACnE,QAAI,SAAS,WAAW;AACtB,UAAI,IAAI,OAAQ,SAAQ,WAAW;AACnC,UAAI,UAAU,IAAK,SAAQ,CAAC,CAAC;AAC7B;AAAA,IACF;AACA,QAAI,UAAU,KAAK;AAAE,cAAQ,SAAS;AAAG,iBAAW,IAAI;AAAG;AAAA,IAAO;AAClE,QAAI,CAAC,SAAS;AACZ,UAAI,IAAI,UAAW,gBAAe,CAAC,MAAM,KAAK,IAAI,YAAY,SAAS,GAAG,IAAI,CAAC,CAAC;AAChF,UAAI,IAAI,QAAS,gBAAe,CAAC,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;AACzD,UAAI,IAAI,QAAQ;AAAE,mBAAW,IAAI;AAAG,eAAO,QAAQ;AAAA,MAAE;AACrD;AAAA,IACF;AACA,QAAI,IAAI,QAAQ;AAAE,iBAAW,KAAK;AAAG,aAAO,QAAQ;AAAG,gBAAU,CAAC;AAAA,IAAE;AACpE,QAAI,IAAI,KAAK;AAAE,aAAO,CAAC,MAAO,MAAM,WAAW,YAAY,QAAS;AAAG,gBAAU,CAAC;AAAA,IAAE;AACpF,QAAI,QAAQ,WAAW;AACrB,UAAI,UAAU,QAAQ,CAAC,QAAQ,SAAS,OAAO,KAAK,OAAQ,WAAU,CAAC,MAAM,IAAI,IAAI;AACrF,UAAI,UAAU,OAAO,SAAS,QAAQ,EAAG,WAAU,CAAC,MAAM,IAAI,IAAI;AAClE,UAAI,UAAU,IAAK,cAAa,CAAC,MAAM,CAAC,CAAC;AAAA,IAC3C;AAAA,EACF,CAAC;AAED,MAAI,SAAS,UAAW,QAAO,gBAAAF,KAAC,gBAAa,WAAsB,MAAM,MAAM,OAAc;AAE7F,SACE,gBAAAC,MAACE,MAAA,EAAI,eAAc,UACjB;AAAA,oBAAAF,MAACG,OAAA,EAAK,MAAI,MAAC;AAAA;AAAA,MAAoB;AAAA,MAAU;AAAA,MAAC,gBAAAJ,KAACI,OAAA,EAAK,UAAQ,MAAC,2EAAgC;AAAA,OAAO;AAAA,IAChG,gBAAAH,MAACE,MAAA,EAAI,WAAW,GACd;AAAA,sBAAAH,KAAC,aAAU,QAAgB,YAAY,WAAY,GAAI,aAAa,SAAY,EAAE,SAAS,IAAI,CAAC,GAAI;AAAA,MACpG,gBAAAA,KAAC,kBAAe,UAAU,YAAY,EAAE,OAAO,WAAW,aAAa,CAAC,EAAE,GAAG,aAA0B;AAAA,MACtG,WAAW,QAAQ,aAAa,UAC7B,gBAAAA,KAAC,eAAY,YAAY,SAAS,MAAY,WAAuB,GAAI,WAAW,SAAY,EAAE,OAAO,OAAO,IAAI,CAAC,GAAI,IACzH,gBAAAA,KAAC,cAAW,YAAY,UAAU,UAAU,QAAW;AAAA,OAC7D;AAAA,KACF;AAEJ;;;AM1HA,SAAS,WAAW,mBAAmB;AACvC,SAAS,qBAAqB;AAQ9B,eAAsB,oBAAoB,UAAoC;AAC5E,QAAM,MAAM,YAAY,QAAQ;AAChC,MAAI,aAAa,KAAK,GAAG,GAAG;AAC1B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,QAAM,MAAO,MAAM,OAAO,cAAc,GAAG,EAAE;AAC7C,QAAM,QAAQ,IAAI,WAAW;AAC7B,SAAO,OAAO,UAAU,aAAa,MAAO,MAAiC,IAAI;AACnF;AAGO,SAAS,cAAc,MAAyB,KAA4C;AACjG,QAAM,OAAO,KAAK,KAAK,CAAC,MAAM,EAAE,WAAW,WAAW,CAAC;AACvD,MAAI,KAAM,QAAO,KAAK,MAAM,YAAY,MAAM;AAC9C,MAAI,IAAI,aAAc,QAAO,IAAI;AACjC,SAAO;AACT;;;ACfO,SAAS,aAAa,UAAkB,UAAyB,CAAC,GAAoB;AAC3F,QAAM,QAAS,QAAQ,SAAS,QAAQ;AACxC,QAAM,SAAS,QAAQ,UAAU,QAAQ;AACzC,SAAO,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC9C,WAAO,MAAM,QAAQ;AACrB,UAAM,aAAa,IAAI;AACvB,QAAI,MAAM;AACV,UAAM,SAAS,CAAC,UAA2B;AACzC,YAAM,IAAI,MAAM,SAAS;AACzB,iBAAW,MAAM,GAAG;AAClB,YAAI,OAAO,QAAQ,OAAO,MAAM;AAC9B,iBAAO,MAAM,IAAI;AACjB,gBAAM,aAAa,KAAK;AACxB,gBAAM,eAAe,QAAQ,MAAM;AACnC,kBAAQ,GAAG;AACX;AAAA,QACF;AACA,YAAI,OAAO,KAAQ;AACjB,iBAAO,MAAM,IAAI;AACjB,gBAAM,aAAa,KAAK;AACxB,gBAAM,eAAe,QAAQ,MAAM;AACnC,iBAAO,IAAI,MAAM,SAAS,CAAC;AAC3B;AAAA,QACF;AACA,YAAI,OAAO,UAAU,OAAO,MAAQ;AAClC,cAAI,IAAI,SAAS,GAAG;AAAE,kBAAM,IAAI,MAAM,GAAG,EAAE;AAAG,mBAAO,MAAM,OAAO;AAAA,UAAE;AACpE;AAAA,QACF;AACA,eAAO;AACP,eAAO,MAAM,QAAG;AAAA,MAClB;AAAA,IACF;AACA,UAAM,GAAG,QAAQ,MAAM;AAAA,EACzB,CAAC;AACH;;;ARYI,gBAAAK,YAAA;AAhDJ,SAAS,KAAK,KAAoB;AAChC,UAAQ,OAAO,MAAM,kBAAkB,GAAG;AAAA,CAAI;AAC9C,UAAQ,KAAK,CAAC;AAChB;AAEA,eAAe,OAAsB;AACnC,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,QAAM,aAAa,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,IAAI,CAAC;AACvD,MAAI,CAAC,WAAY,MAAK,uEAAkE;AACxF,QAAM,YAAY,KAAK,KAAK,CAAC,MAAM,EAAE,WAAW,UAAU,CAAC;AAC3D,MAAI,CAAC,UAAW,MAAK,wBAAwB;AAC7C,QAAM,YAAY,UAAU,MAAM,WAAW,MAAM;AAEnD,MAAI,SAAS,cAAc,MAAM,QAAQ,GAAG;AAC5C,MAAI,WAAW,QAAW;AACxB,QAAI,CAAC,QAAQ,MAAM,MAAO,MAAK,2DAAiD;AAChF,aAAS,MAAM,aAAa,UAAU;AAAA,EACxC;AAEA,MAAI;AACJ,MAAI;AACF,kBAAe,MAAM,oBAAoB,UAAU;AAAA,EACrD,SAAS,KAAK;AACZ,SAAK,0BAA0B,UAAU,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,EACnG;AAEA,MAAI;AACJ,MAAI,KAAK,SAAS,SAAS,KAAK,YAAY,OAAO;AAEjD,UAAM,UAAU,QAAQ,YAAY,KAAK;AACzC,kBAAc,EAAE,GAAG,aAAa,OAAO,QAAQ;AAC/C,YAAQ,QAAQ;AAAA,EAClB;AAGA,QAAM,UAAwB,EAAE,GAAG,aAAa,OAAe;AAC/D,QAAM,KAAK,MAAM,YAAY,OAAO;AAEpC,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM,GAAG,UAAU,SAAS;AAAA,EACtC,SAAS,KAAK;AACZ,SAAK,yBAAyB,SAAS,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,EAAE;AAAA,EACjG;AAEA,QAAM,YAAY,gBAAgB,IAAI,QAAQ,EAAE,MAAM,IAAI,MAAS;AACnE,QAAM,UAAU,EAAE,QAAQ,MAAM,UAAU,WAAW,GAAG,UAAU,MAAM,UAAU,SAAS,KAAK,EAAE;AAClG,QAAM,EAAE,cAAc,IAAI;AAAA,IACxB,gBAAAA,KAAC,OAAI,WAAsB,OAAc,WAAsB,SAAkB;AAAA,EACnF;AACA,QAAM,cAAc;AACtB;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC,CAAC;","names":["React","Box","Text","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","Box","Text","jsx","jsxs","jsx","jsxs","React","Box","Text","jsx"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@noy-db/in-devtools-tui",
|
|
3
|
-
"version": "0.4.0-pre.
|
|
3
|
+
"version": "0.4.0-pre.10",
|
|
4
4
|
"description": "Interactive terminal inspector for a live noy-db (ink TUI over @noy-db/in-devtools).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -15,18 +15,18 @@
|
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"ink": "^5.0.1",
|
|
17
17
|
"react": "^18.3.1",
|
|
18
|
-
"@noy-db/to-meter": "0.4.0-pre.
|
|
18
|
+
"@noy-db/to-meter": "0.4.0-pre.10"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
|
-
"@noy-db/hub": "0.4.0-pre.
|
|
22
|
-
"@noy-db/in-devtools": "0.4.0-pre.
|
|
21
|
+
"@noy-db/hub": "0.4.0-pre.10",
|
|
22
|
+
"@noy-db/in-devtools": "0.4.0-pre.10"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"ink-testing-library": "^4.0.0",
|
|
26
26
|
"@types/node": "^22.0.0",
|
|
27
27
|
"@types/react": "^18.3.12",
|
|
28
|
-
"@noy-db/
|
|
29
|
-
"@noy-db/
|
|
28
|
+
"@noy-db/hub": "0.4.0-pre.10",
|
|
29
|
+
"@noy-db/in-devtools": "0.4.0-pre.10"
|
|
30
30
|
},
|
|
31
31
|
"engines": {
|
|
32
32
|
"node": ">=22.0.0"
|