latticesql 4.3.0 → 4.3.2
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/cli.js +176 -77
- package/dist/desktop-entry.js +172 -73
- package/dist/gui-assets/ort/ort-wasm-simd-threaded.asyncify.mjs +112 -0
- package/dist/gui-assets/ort/ort-wasm-simd-threaded.jsep.mjs +106 -0
- package/dist/gui-assets/ort/ort-wasm-simd-threaded.mjs +59 -0
- package/dist/index.cjs +130 -39
- package/dist/index.js +176 -77
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -29084,12 +29084,12 @@ var getNodeModulesParentDirs;
|
|
|
29084
29084
|
var init_getNodeModulesParentDirs = __esm({
|
|
29085
29085
|
"node_modules/@aws-sdk/core/dist-es/submodules/client/util-user-agent-node/getNodeModulesParentDirs.js"() {
|
|
29086
29086
|
"use strict";
|
|
29087
|
-
getNodeModulesParentDirs = (
|
|
29087
|
+
getNodeModulesParentDirs = (dirname20) => {
|
|
29088
29088
|
const cwd = process.cwd();
|
|
29089
|
-
if (!
|
|
29089
|
+
if (!dirname20) {
|
|
29090
29090
|
return [cwd];
|
|
29091
29091
|
}
|
|
29092
|
-
const normalizedPath = normalize(
|
|
29092
|
+
const normalizedPath = normalize(dirname20);
|
|
29093
29093
|
const parts = normalizedPath.split(sep6);
|
|
29094
29094
|
const nodeModulesIndex = parts.indexOf("node_modules");
|
|
29095
29095
|
const parentDir = nodeModulesIndex !== -1 ? parts.slice(0, nodeModulesIndex).join(sep6) : normalizedPath;
|
|
@@ -29167,8 +29167,8 @@ var init_getTypeScriptUserAgentPair = __esm({
|
|
|
29167
29167
|
tscVersion = null;
|
|
29168
29168
|
return void 0;
|
|
29169
29169
|
}
|
|
29170
|
-
const
|
|
29171
|
-
const nodeModulesParentDirs = getNodeModulesParentDirs(
|
|
29170
|
+
const dirname20 = typeof __dirname !== "undefined" ? __dirname : void 0;
|
|
29171
|
+
const nodeModulesParentDirs = getNodeModulesParentDirs(dirname20);
|
|
29172
29172
|
let versionFromApp;
|
|
29173
29173
|
for (const nodeModulesParentDir of nodeModulesParentDirs) {
|
|
29174
29174
|
try {
|
|
@@ -57954,8 +57954,8 @@ var init_dist_es22 = __esm({
|
|
|
57954
57954
|
});
|
|
57955
57955
|
|
|
57956
57956
|
// src/cli.ts
|
|
57957
|
-
import { resolve as resolve17, dirname as
|
|
57958
|
-
import { readFileSync as readFileSync26, existsSync as
|
|
57957
|
+
import { resolve as resolve17, dirname as dirname19 } from "path";
|
|
57958
|
+
import { readFileSync as readFileSync26, existsSync as existsSync34 } from "fs";
|
|
57959
57959
|
import { execSync } from "child_process";
|
|
57960
57960
|
import { parse as parse3 } from "yaml";
|
|
57961
57961
|
|
|
@@ -58222,9 +58222,9 @@ function installLatest(ctx, version, opts = {}) {
|
|
|
58222
58222
|
init_http();
|
|
58223
58223
|
import { createServer } from "http";
|
|
58224
58224
|
import { spawn as spawn2 } from "child_process";
|
|
58225
|
-
import { existsSync as
|
|
58225
|
+
import { existsSync as existsSync33 } from "fs";
|
|
58226
58226
|
import { WebSocketServer, WebSocket } from "ws";
|
|
58227
|
-
import { dirname as
|
|
58227
|
+
import { dirname as dirname18, resolve as resolve16 } from "path";
|
|
58228
58228
|
|
|
58229
58229
|
// src/gui/active-db.ts
|
|
58230
58230
|
init_adapter();
|
|
@@ -60429,12 +60429,16 @@ var tokensCss = `
|
|
|
60429
60429
|
surface (a bare input on a modal, the Database wizard, User Config, etc.):
|
|
60430
60430
|
dark text on a white field with a light border. Placeholders use the
|
|
60431
60431
|
muted token. Affects every input/select/textarea across the GUI. */
|
|
60432
|
-
|
|
60432
|
+
/* Text-like fields only \u2014 radios/checkboxes keep their native rendering
|
|
60433
|
+
(the box/border treatment mangles them). The accent color tints the native
|
|
60434
|
+
controls so checked radios/checkboxes are on-brand blue. */
|
|
60435
|
+
input:not([type='radio']):not([type='checkbox']):not([type='range']), select, textarea {
|
|
60433
60436
|
color: var(--text);
|
|
60434
60437
|
background: var(--surface);
|
|
60435
60438
|
border: 1px solid var(--border);
|
|
60436
60439
|
border-radius: 6px;
|
|
60437
60440
|
}
|
|
60441
|
+
input[type='radio'], input[type='checkbox'] { accent-color: var(--accent); }
|
|
60438
60442
|
input::placeholder, textarea::placeholder {
|
|
60439
60443
|
color: var(--text-muted);
|
|
60440
60444
|
opacity: 1;
|
|
@@ -61419,7 +61423,7 @@ var teamsCss = ` /* \u2500\u2500 Teams (Project Config + User Config) \u2500\
|
|
|
61419
61423
|
color: var(--text); font-weight: 500;
|
|
61420
61424
|
text-transform: uppercase; letter-spacing: 0.04em;
|
|
61421
61425
|
}
|
|
61422
|
-
.modal .field input, .modal .field textarea {
|
|
61426
|
+
.modal .field input:not([type='radio']):not([type='checkbox']), .modal .field textarea {
|
|
61423
61427
|
width: 100%; padding: 6px 8px;
|
|
61424
61428
|
background: var(--surface); color: var(--text);
|
|
61425
61429
|
border: 1px solid var(--border-strong);
|
|
@@ -61429,6 +61433,20 @@ var teamsCss = ` /* \u2500\u2500 Teams (Project Config + User Config) \u2500\
|
|
|
61429
61433
|
color: var(--text-muted);
|
|
61430
61434
|
}
|
|
61431
61435
|
.modal .field textarea { min-height: 60px; font-family: ui-monospace, monospace; font-size: 12px; }
|
|
61436
|
+
/* New-workspace "Kind" selector \u2014 clean cards, blue-highlighted selection. */
|
|
61437
|
+
.wiz-kind-opts { display: flex; gap: 10px; margin-top: 6px; flex-wrap: wrap; }
|
|
61438
|
+
.wiz-kind-card {
|
|
61439
|
+
flex: 1 1 0; min-width: 132px; display: flex; align-items: center; gap: 9px;
|
|
61440
|
+
padding: 10px 12px; border: 1px solid var(--border); border-radius: 8px;
|
|
61441
|
+
background: var(--surface); cursor: pointer;
|
|
61442
|
+
transition: border-color 0.12s ease, background 0.12s ease;
|
|
61443
|
+
}
|
|
61444
|
+
.wiz-kind-card:hover { border-color: var(--border-strong); }
|
|
61445
|
+
.wiz-kind-card:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
|
|
61446
|
+
.wiz-kind-card input { margin: 0; flex: 0 0 auto; }
|
|
61447
|
+
.wiz-kind-name { font-size: 13px; color: var(--text); text-transform: none; letter-spacing: 0; }
|
|
61448
|
+
.wiz-kind-sub { color: var(--text-muted); font-size: 11px; margin-left: 2px; }
|
|
61449
|
+
.wiz-kind-card:has(input:checked) .wiz-kind-name { color: var(--accent-deep); font-weight: 500; }
|
|
61432
61450
|
.modal .copy-token {
|
|
61433
61451
|
padding: 8px 10px; background: var(--surface-2); border: 1px solid var(--border);
|
|
61434
61452
|
border-radius: 4px; font-family: ui-monospace, monospace; font-size: 12px;
|
|
@@ -62674,6 +62692,9 @@ var bootJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
62674
62692
|
initRailDragDrop();
|
|
62675
62693
|
renderComposer();
|
|
62676
62694
|
initThreadControls();
|
|
62695
|
+
// Warm up on-device voice in the background shortly after boot so dictation
|
|
62696
|
+
// is ready on first use \u2014 no visible model-loading step, ever.
|
|
62697
|
+
if (typeof voicePreload === 'function') setTimeout(voicePreload, 1500);
|
|
62677
62698
|
checkNativeSetup();
|
|
62678
62699
|
// App is fully populated \u2014 reveal it (Feature C).
|
|
62679
62700
|
hideAppLoading();
|
|
@@ -66437,9 +66458,14 @@ var dashboardJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
|
66437
66458
|
}
|
|
66438
66459
|
var d = displayFor(table);
|
|
66439
66460
|
// The tab shows the open RECORD's name (e.g. an entity row), not the
|
|
66440
|
-
// object/table name.
|
|
66461
|
+
// object/table name. Guard: only retitle a RECORD ('item:') tab \u2014 never the
|
|
66462
|
+
// shared Brain Graph ('graph') tab, even if a record render briefly runs
|
|
66463
|
+
// while the hash still resolves to the graph (which would rename \u{1F9E0}).
|
|
66441
66464
|
if (typeof setTabTitle === 'function') {
|
|
66442
|
-
|
|
66465
|
+
var fsItemKey = tabKeyForHash(location.hash);
|
|
66466
|
+
if (fsItemKey && fsItemKey.indexOf('item:') === 0) {
|
|
66467
|
+
setTabTitle(fsItemKey, fsDisplayName(row) || d.label);
|
|
66468
|
+
}
|
|
66443
66469
|
}
|
|
66444
66470
|
// Files + artifacts get the two-view document layout (formatted display +
|
|
66445
66471
|
// a View Source toggle) with a Version History + Delete dropdown \u2014 not the
|
|
@@ -66509,7 +66535,10 @@ var dashboardJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
|
66509
66535
|
// The tab shows the FILE's name (e.g. "Properties Dashboard"), not the
|
|
66510
66536
|
// object name ("Files").
|
|
66511
66537
|
if (typeof setTabTitle === 'function') {
|
|
66512
|
-
|
|
66538
|
+
var fsDocKey = tabKeyForHash(location.hash);
|
|
66539
|
+
if (fsDocKey && fsDocKey.indexOf('item:') === 0) {
|
|
66540
|
+
setTabTitle(fsDocKey, fsDisplayName(row) || d.label);
|
|
66541
|
+
}
|
|
66513
66542
|
}
|
|
66514
66543
|
var mode = fileViewMode[id] || 'display';
|
|
66515
66544
|
// Actions live in a dropdown menu next to the title; View source / Version
|
|
@@ -68716,15 +68745,18 @@ var dataModelJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
|
68716
68745
|
return '' +
|
|
68717
68746
|
nameField +
|
|
68718
68747
|
'<div class="field"><label>Kind</label>' +
|
|
68719
|
-
'<div
|
|
68720
|
-
'<label
|
|
68721
|
-
'<input type="radio" name="wiz-kind" value="local"' + (kind === 'local' ? ' checked' : '') + ' />
|
|
68748
|
+
'<div class="wiz-kind-opts">' +
|
|
68749
|
+
'<label class="wiz-kind-card">' +
|
|
68750
|
+
'<input type="radio" name="wiz-kind" value="local"' + (kind === 'local' ? ' checked' : '') + ' />' +
|
|
68751
|
+
'<span class="wiz-kind-name">New local <span class="wiz-kind-sub">SQLite</span></span>' +
|
|
68722
68752
|
'</label>' +
|
|
68723
|
-
'<label
|
|
68724
|
-
'<input type="radio" name="wiz-kind" value="cloud"' + (kind === 'cloud' ? ' checked' : '') + ' />
|
|
68753
|
+
'<label class="wiz-kind-card">' +
|
|
68754
|
+
'<input type="radio" name="wiz-kind" value="cloud"' + (kind === 'cloud' ? ' checked' : '') + ' />' +
|
|
68755
|
+
'<span class="wiz-kind-name">New cloud <span class="wiz-kind-sub">Postgres</span></span>' +
|
|
68725
68756
|
'</label>' +
|
|
68726
|
-
'<label
|
|
68727
|
-
'<input type="radio" name="wiz-kind" value="join"' + (kind === 'join' ? ' checked' : '') + ' />
|
|
68757
|
+
'<label class="wiz-kind-card">' +
|
|
68758
|
+
'<input type="radio" name="wiz-kind" value="join"' + (kind === 'join' ? ' checked' : '') + ' />' +
|
|
68759
|
+
'<span class="wiz-kind-name">Join a team <span class="wiz-kind-sub">invite</span></span>' +
|
|
68728
68760
|
'</label>' +
|
|
68729
68761
|
'</div>' +
|
|
68730
68762
|
'<p style="font-size:11px;color:var(--text-muted);margin:6px 0 0">' +
|
|
@@ -70869,6 +70901,14 @@ var voiceLocalJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
70869
70901
|
return _voiceWorker;
|
|
70870
70902
|
}
|
|
70871
70903
|
|
|
70904
|
+
// Warm up the voice worker + model in the BACKGROUND on launch, so dictation is
|
|
70905
|
+
// ready by the time the user records and any first-run weight fetch happens
|
|
70906
|
+
// silently up front (never mid-recording, never with a visible "downloading"
|
|
70907
|
+
// state). Idempotent + best-effort \u2014 a failure just leaves the mic to lazy-init.
|
|
70908
|
+
function voicePreload() {
|
|
70909
|
+
try { getVoiceWorker(); } catch (_) { /* best-effort */ }
|
|
70910
|
+
}
|
|
70911
|
+
|
|
70872
70912
|
function voicePreferredDevice() {
|
|
70873
70913
|
// WebGPU when the browser exposes it, else WASM. The worker downgrades to
|
|
70874
70914
|
// wasm itself if the runtime can't honor webgpu, so this is just a hint.
|
|
@@ -70890,14 +70930,14 @@ var voiceLocalJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
70890
70930
|
_voiceWorkerReady = false;
|
|
70891
70931
|
}
|
|
70892
70932
|
|
|
70893
|
-
//
|
|
70894
|
-
//
|
|
70895
|
-
//
|
|
70896
|
-
|
|
70897
|
-
|
|
70898
|
-
|
|
70899
|
-
|
|
70900
|
-
|
|
70933
|
+
// Model loading is SILENT \u2014 the user never sees a "downloading voice model"
|
|
70934
|
+
// state. The worker + model are warmed up in the background on launch (see
|
|
70935
|
+
// voicePreload), and the ORT runtime ships bundled, so by the time anyone
|
|
70936
|
+
// records, dictation is ready. We intentionally surface no loading progress in
|
|
70937
|
+
// the composer; if a first-run weight fetch is still in flight, the existing
|
|
70938
|
+
// "Transcribing\u2026" placeholder covers it.
|
|
70939
|
+
function onVoiceProgress(_file, _progress) {
|
|
70940
|
+
/* intentionally silent \u2014 no visible voice-model loading UI */
|
|
70901
70941
|
}
|
|
70902
70942
|
|
|
70903
70943
|
// Decode a recorded audio blob to mono 16 kHz PCM (Float32Array), entirely in
|
|
@@ -71901,12 +71941,33 @@ var sourcesJs = `
|
|
|
71901
71941
|
'<span class="src-name">' + escapeHtml(name) + '</span></div></li>';
|
|
71902
71942
|
}).join('') + '</ul>'
|
|
71903
71943
|
: '';
|
|
71944
|
+
// Preserve expanded folders across this re-render so an in-progress
|
|
71945
|
+
// ingest (which re-renders the sidebar) never snaps an open folder shut.
|
|
71946
|
+
// Capture each expanded folder's path + its lazily-loaded children markup,
|
|
71947
|
+
// then re-attach + re-open them after the rebuild (no re-fetch, no flicker).
|
|
71948
|
+
var openFolders = {};
|
|
71949
|
+
host.querySelectorAll('.src-folder[data-loaded="1"]').forEach(function (li) {
|
|
71950
|
+
var ul0 = li.querySelector(':scope > .src-children');
|
|
71951
|
+
if (ul0 && !ul0.hidden) openFolders[li.getAttribute('data-path')] = ul0.innerHTML;
|
|
71952
|
+
});
|
|
71904
71953
|
if (!rootsHtml && !looseHtml) {
|
|
71905
71954
|
host.innerHTML = '<div class="src-empty">No files yet.</div>';
|
|
71906
71955
|
return;
|
|
71907
71956
|
}
|
|
71908
71957
|
host.innerHTML = rootsHtml + looseHtml;
|
|
71909
71958
|
wireSourceTree(host);
|
|
71959
|
+
host.querySelectorAll('.src-folder').forEach(function (li) {
|
|
71960
|
+
var saved = openFolders[li.getAttribute('data-path')];
|
|
71961
|
+
if (saved == null) return;
|
|
71962
|
+
var ul1 = li.querySelector(':scope > .src-children');
|
|
71963
|
+
var caret = li.querySelector(':scope > .src-row > .src-caret');
|
|
71964
|
+
if (!ul1) return;
|
|
71965
|
+
ul1.innerHTML = saved;
|
|
71966
|
+
ul1.hidden = false;
|
|
71967
|
+
li.setAttribute('data-loaded', '1');
|
|
71968
|
+
if (caret) caret.textContent = '\u25BE';
|
|
71969
|
+
wireSourceTree(ul1);
|
|
71970
|
+
});
|
|
71910
71971
|
})
|
|
71911
71972
|
.catch(function () { host.innerHTML = ''; });
|
|
71912
71973
|
}
|
|
@@ -76697,8 +76758,16 @@ async function dispatchIngestRoute(req, res, ctx) {
|
|
|
76697
76758
|
|
|
76698
76759
|
// src/gui/sources-routes.ts
|
|
76699
76760
|
init_user_config();
|
|
76700
|
-
import {
|
|
76701
|
-
|
|
76761
|
+
import {
|
|
76762
|
+
statSync as statSync9,
|
|
76763
|
+
readdirSync as readdirSync8,
|
|
76764
|
+
readFileSync as readFileSync23,
|
|
76765
|
+
writeFileSync as writeFileSync10,
|
|
76766
|
+
existsSync as existsSync27,
|
|
76767
|
+
mkdirSync as mkdirSync12,
|
|
76768
|
+
rmSync
|
|
76769
|
+
} from "fs";
|
|
76770
|
+
import { resolve as resolve12, join as join29, basename as basename12, sep as sep8, dirname as dirname16 } from "path";
|
|
76702
76771
|
import { execFile } from "child_process";
|
|
76703
76772
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
76704
76773
|
init_http();
|
|
@@ -76706,20 +76775,49 @@ var MAX_LIST_ENTRIES = 2e3;
|
|
|
76706
76775
|
var MAX_INGEST_FILES = 500;
|
|
76707
76776
|
var MAX_INGEST_DEPTH = 8;
|
|
76708
76777
|
var SKIP_DIRS = /* @__PURE__ */ new Set([".git", "node_modules", ".DS_Store", "__pycache__", ".venv", "venv"]);
|
|
76709
|
-
function rootsFile() {
|
|
76710
|
-
return join29(
|
|
76778
|
+
function rootsFile(configPath) {
|
|
76779
|
+
return join29(dirname16(configPath), "sources.json");
|
|
76780
|
+
}
|
|
76781
|
+
function migrateGlobalRootsIfNeeded(configPath) {
|
|
76782
|
+
const wsFile = rootsFile(configPath);
|
|
76783
|
+
if (existsSync27(wsFile)) return;
|
|
76784
|
+
const globalFile = join29(configDir(), "sources.json");
|
|
76785
|
+
if (globalFile === wsFile || !existsSync27(globalFile)) return;
|
|
76786
|
+
let roots;
|
|
76787
|
+
try {
|
|
76788
|
+
const parsed = JSON.parse(readFileSync23(globalFile, "utf8"));
|
|
76789
|
+
if (!Array.isArray(parsed.roots) || parsed.roots.length === 0) return;
|
|
76790
|
+
roots = parsed.roots;
|
|
76791
|
+
} catch {
|
|
76792
|
+
return;
|
|
76793
|
+
}
|
|
76794
|
+
try {
|
|
76795
|
+
mkdirSync12(dirname16(wsFile), { recursive: true });
|
|
76796
|
+
writeFileSync10(wsFile, JSON.stringify({ roots }, null, 2), "utf8");
|
|
76797
|
+
} catch {
|
|
76798
|
+
return;
|
|
76799
|
+
}
|
|
76800
|
+
try {
|
|
76801
|
+
rmSync(globalFile, { force: true });
|
|
76802
|
+
} catch {
|
|
76803
|
+
try {
|
|
76804
|
+
writeFileSync10(globalFile, JSON.stringify({ roots: [] }, null, 2), "utf8");
|
|
76805
|
+
} catch {
|
|
76806
|
+
}
|
|
76807
|
+
}
|
|
76711
76808
|
}
|
|
76712
|
-
function readRoots() {
|
|
76809
|
+
function readRoots(configPath) {
|
|
76810
|
+
migrateGlobalRootsIfNeeded(configPath);
|
|
76713
76811
|
try {
|
|
76714
|
-
const raw = readFileSync23(rootsFile(), "utf8");
|
|
76812
|
+
const raw = readFileSync23(rootsFile(configPath), "utf8");
|
|
76715
76813
|
const parsed = JSON.parse(raw);
|
|
76716
76814
|
return Array.isArray(parsed.roots) ? parsed.roots : [];
|
|
76717
76815
|
} catch {
|
|
76718
76816
|
return [];
|
|
76719
76817
|
}
|
|
76720
76818
|
}
|
|
76721
|
-
function writeRoots(roots) {
|
|
76722
|
-
writeFileSync10(rootsFile(), JSON.stringify({ roots }, null, 2), "utf8");
|
|
76819
|
+
function writeRoots(configPath, roots) {
|
|
76820
|
+
writeFileSync10(rootsFile(configPath), JSON.stringify({ roots }, null, 2), "utf8");
|
|
76723
76821
|
}
|
|
76724
76822
|
function safeResolveInside2(target, roots) {
|
|
76725
76823
|
const abs = resolve12(target);
|
|
@@ -76809,14 +76907,14 @@ async function ingestFolder(abs, ingestFile) {
|
|
|
76809
76907
|
return { ingested, skipped };
|
|
76810
76908
|
}
|
|
76811
76909
|
async function dispatchSourcesRoute(req, res, deps) {
|
|
76812
|
-
const { pathname, method, ingestFile } = deps;
|
|
76910
|
+
const { pathname, method, ingestFile, configPath } = deps;
|
|
76813
76911
|
if (!pathname.startsWith("/api/sources/")) return false;
|
|
76814
76912
|
if (!localFileOpenEnabled()) {
|
|
76815
76913
|
sendJson(res, { enabled: false });
|
|
76816
76914
|
return true;
|
|
76817
76915
|
}
|
|
76818
76916
|
if (pathname === "/api/sources/roots" && method === "GET") {
|
|
76819
|
-
sendJson(res, { enabled: true, roots: readRoots() });
|
|
76917
|
+
sendJson(res, { enabled: true, roots: readRoots(configPath) });
|
|
76820
76918
|
return true;
|
|
76821
76919
|
}
|
|
76822
76920
|
if (pathname === "/api/sources/roots" && method === "POST") {
|
|
@@ -76842,12 +76940,12 @@ async function dispatchSourcesRoute(req, res, deps) {
|
|
|
76842
76940
|
sendJson(res, { error: `path not found: ${abs}` }, 400);
|
|
76843
76941
|
return true;
|
|
76844
76942
|
}
|
|
76845
|
-
const roots = readRoots();
|
|
76943
|
+
const roots = readRoots(configPath);
|
|
76846
76944
|
let root6 = roots.find((r6) => resolve12(r6.path) === abs);
|
|
76847
76945
|
if (!root6) {
|
|
76848
76946
|
root6 = { id: randomUUID4(), path: abs, kind, name: basename12(abs) || abs };
|
|
76849
76947
|
roots.push(root6);
|
|
76850
|
-
writeRoots(roots);
|
|
76948
|
+
writeRoots(configPath, roots);
|
|
76851
76949
|
}
|
|
76852
76950
|
let result;
|
|
76853
76951
|
if (kind === "folder") result = await ingestFolder(abs, ingestFile);
|
|
@@ -76858,8 +76956,8 @@ async function dispatchSourcesRoute(req, res, deps) {
|
|
|
76858
76956
|
const delMatch = /^\/api\/sources\/roots\/([^/]+)$/.exec(pathname);
|
|
76859
76957
|
if (delMatch && method === "DELETE") {
|
|
76860
76958
|
const id = decodeURIComponent(delMatch[1] ?? "");
|
|
76861
|
-
const roots = readRoots().filter((r6) => r6.id !== id);
|
|
76862
|
-
writeRoots(roots);
|
|
76959
|
+
const roots = readRoots(configPath).filter((r6) => r6.id !== id);
|
|
76960
|
+
writeRoots(configPath, roots);
|
|
76863
76961
|
sendJson(res, { ok: true });
|
|
76864
76962
|
return true;
|
|
76865
76963
|
}
|
|
@@ -76877,7 +76975,7 @@ async function dispatchSourcesRoute(req, res, deps) {
|
|
|
76877
76975
|
sendJson(res, { error: "path is required" }, 400);
|
|
76878
76976
|
return true;
|
|
76879
76977
|
}
|
|
76880
|
-
const abs = safeResolveInside2(target, readRoots());
|
|
76978
|
+
const abs = safeResolveInside2(target, readRoots(configPath));
|
|
76881
76979
|
if (!abs) {
|
|
76882
76980
|
sendJson(res, { error: "path is outside any registered source root" }, 403);
|
|
76883
76981
|
return true;
|
|
@@ -76892,7 +76990,7 @@ async function dispatchSourcesRoute(req, res, deps) {
|
|
|
76892
76990
|
if (pathname === "/api/sources/ingest-folder" && method === "POST") {
|
|
76893
76991
|
const body = await readJson(req).catch(() => ({}));
|
|
76894
76992
|
const target = typeof body.path === "string" ? body.path : "";
|
|
76895
|
-
const abs = safeResolveInside2(target, readRoots());
|
|
76993
|
+
const abs = safeResolveInside2(target, readRoots(configPath));
|
|
76896
76994
|
if (!abs) {
|
|
76897
76995
|
sendJson(res, { error: "path is outside any registered source root" }, 403);
|
|
76898
76996
|
return true;
|
|
@@ -76906,7 +77004,7 @@ async function dispatchSourcesRoute(req, res, deps) {
|
|
|
76906
77004
|
// src/gui/import-routes.ts
|
|
76907
77005
|
init_adapter();
|
|
76908
77006
|
init_http();
|
|
76909
|
-
import { existsSync as
|
|
77007
|
+
import { existsSync as existsSync28, readFileSync as readFileSync24, statSync as statSync10 } from "fs";
|
|
76910
77008
|
import { isAbsolute as isAbsolute4, join as join30 } from "path";
|
|
76911
77009
|
init_native_entities();
|
|
76912
77010
|
function badRequest(message) {
|
|
@@ -76940,7 +77038,7 @@ async function readImportSourceFromFile(db, fileId, latticeRoot) {
|
|
|
76940
77038
|
);
|
|
76941
77039
|
if (!row) throw badRequest("Unknown import file: " + fileId);
|
|
76942
77040
|
const path3 = localPathOf2(row, latticeRoot);
|
|
76943
|
-
if (!path3 || !
|
|
77041
|
+
if (!path3 || !existsSync28(path3)) {
|
|
76944
77042
|
throw badRequest("The import file\u2019s bytes are not available locally.");
|
|
76945
77043
|
}
|
|
76946
77044
|
const sizeBytes = statSync10(path3).size;
|
|
@@ -79081,7 +79179,7 @@ init_dispatch();
|
|
|
79081
79179
|
init_column_descriptions();
|
|
79082
79180
|
init_mutations();
|
|
79083
79181
|
init_native_entities();
|
|
79084
|
-
import { createReadStream as createReadStream3, existsSync as
|
|
79182
|
+
import { createReadStream as createReadStream3, existsSync as existsSync29, realpathSync as realpathSync2, statSync as statSync11 } from "fs";
|
|
79085
79183
|
import { extname as extname3, join as join31, normalize as normalize2, sep as sep9 } from "path";
|
|
79086
79184
|
|
|
79087
79185
|
// src/gui/count-many.ts
|
|
@@ -79289,7 +79387,7 @@ async function handleReadRoutes(req, res, ctx, deps) {
|
|
|
79289
79387
|
const base = deps.guiAssetsDir.replace(/[/\\]+$/, "");
|
|
79290
79388
|
const target = normalize2(join31(base, rel));
|
|
79291
79389
|
const within = target === base || target.startsWith(base + sep9);
|
|
79292
|
-
if (!within || !
|
|
79390
|
+
if (!within || !existsSync29(target) || !statSync11(target).isFile()) {
|
|
79293
79391
|
sendJson(res, { error: "asset not found" }, 404);
|
|
79294
79392
|
return true;
|
|
79295
79393
|
}
|
|
@@ -80497,16 +80595,16 @@ async function handleHistoryRoutes(req, res, ctx, deps) {
|
|
|
80497
80595
|
// src/gui/workspaces-routes.ts
|
|
80498
80596
|
init_http();
|
|
80499
80597
|
import { resolve as resolve13 } from "path";
|
|
80500
|
-
import { existsSync as
|
|
80598
|
+
import { existsSync as existsSync30, rmSync as rmSync2 } from "fs";
|
|
80501
80599
|
init_workspace();
|
|
80502
80600
|
init_lattice_root();
|
|
80503
80601
|
init_user_config();
|
|
80504
80602
|
function cleanupWorkspaceFiles(root6, ws) {
|
|
80505
80603
|
if (!ws.configPath && ws.kind === "local") {
|
|
80506
|
-
|
|
80604
|
+
rmSync2(workspaceDir(root6, ws.dir), { recursive: true, force: true });
|
|
80507
80605
|
} else if (ws.kind === "cloud") {
|
|
80508
|
-
if (ws.configPath &&
|
|
80509
|
-
|
|
80606
|
+
if (ws.configPath && existsSync30(ws.configPath)) {
|
|
80607
|
+
rmSync2(ws.configPath, { force: true });
|
|
80510
80608
|
}
|
|
80511
80609
|
const labelMatch = /^\$\{LATTICE_DB:([A-Za-z0-9._-]+)\}$/.exec(ws.db.trim());
|
|
80512
80610
|
const label = labelMatch?.[1];
|
|
@@ -80709,15 +80807,15 @@ async function handleWorkspacesRoutes(req, res, ctx, deps) {
|
|
|
80709
80807
|
// src/gui/databases-routes.ts
|
|
80710
80808
|
init_http();
|
|
80711
80809
|
import { basename as basename14, resolve as resolve15 } from "path";
|
|
80712
|
-
import { existsSync as
|
|
80810
|
+
import { existsSync as existsSync32 } from "fs";
|
|
80713
80811
|
init_parser();
|
|
80714
80812
|
|
|
80715
80813
|
// src/gui/config-paths.ts
|
|
80716
80814
|
init_parser();
|
|
80717
|
-
import { basename as basename13, dirname as
|
|
80815
|
+
import { basename as basename13, dirname as dirname17, join as join32, resolve as resolve14 } from "path";
|
|
80718
80816
|
import {
|
|
80719
|
-
existsSync as
|
|
80720
|
-
mkdirSync as
|
|
80817
|
+
existsSync as existsSync31,
|
|
80818
|
+
mkdirSync as mkdirSync13,
|
|
80721
80819
|
readFileSync as readFileSync25,
|
|
80722
80820
|
readdirSync as readdirSync9,
|
|
80723
80821
|
unlinkSync as unlinkSync5,
|
|
@@ -80725,10 +80823,10 @@ import {
|
|
|
80725
80823
|
} from "fs";
|
|
80726
80824
|
import { parseDocument as parseDocument7 } from "yaml";
|
|
80727
80825
|
function resolveOutputDirForConfig(configPath) {
|
|
80728
|
-
const base =
|
|
80826
|
+
const base = dirname17(resolve14(configPath));
|
|
80729
80827
|
for (const dir of ["context", ".", "generated"]) {
|
|
80730
80828
|
const abs = resolve14(base, dir);
|
|
80731
|
-
if (
|
|
80829
|
+
if (existsSync31(join32(abs, ".lattice", "manifest.json"))) return abs;
|
|
80732
80830
|
}
|
|
80733
80831
|
return resolve14(base, "context");
|
|
80734
80832
|
}
|
|
@@ -80737,7 +80835,7 @@ function friendlyConfigName(parsedName, configPath) {
|
|
|
80737
80835
|
return basename13(configPath).replace(/\.(ya?ml)$/, "");
|
|
80738
80836
|
}
|
|
80739
80837
|
function listConfigs(activeConfigPath) {
|
|
80740
|
-
const dir =
|
|
80838
|
+
const dir = dirname17(activeConfigPath);
|
|
80741
80839
|
const entries = [];
|
|
80742
80840
|
for (const fname of readdirSync9(dir)) {
|
|
80743
80841
|
if (!fname.endsWith(".yml") && !fname.endsWith(".yaml")) continue;
|
|
@@ -80766,17 +80864,17 @@ function listConfigs(activeConfigPath) {
|
|
|
80766
80864
|
return entries.sort((a6, b6) => a6.label.localeCompare(b6.label));
|
|
80767
80865
|
}
|
|
80768
80866
|
function createBlankConfig(activeConfigPath, dbName) {
|
|
80769
|
-
const dir =
|
|
80867
|
+
const dir = dirname17(activeConfigPath);
|
|
80770
80868
|
const slug = dbName.toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
80771
80869
|
if (!slug) throw new Error("Workspace name must contain at least one alphanumeric character");
|
|
80772
80870
|
const configPath = join32(dir, `${slug}.config.yml`);
|
|
80773
|
-
if (
|
|
80871
|
+
if (existsSync31(configPath)) throw new Error(`Config already exists: ${slug}.config.yml`);
|
|
80774
80872
|
const yaml = `db: ./data/${slug}.db
|
|
80775
80873
|
|
|
80776
80874
|
entities: {}
|
|
80777
80875
|
`;
|
|
80778
80876
|
writeFileSync11(configPath, yaml, "utf8");
|
|
80779
|
-
|
|
80877
|
+
mkdirSync13(join32(dir, "data"), { recursive: true });
|
|
80780
80878
|
return configPath;
|
|
80781
80879
|
}
|
|
80782
80880
|
function sqliteFileForConfig(configPath) {
|
|
@@ -80785,18 +80883,18 @@ function sqliteFileForConfig(configPath) {
|
|
|
80785
80883
|
if (!raw) return null;
|
|
80786
80884
|
if (isPostgresUrl(raw) || raw.startsWith("${LATTICE_DB:")) return null;
|
|
80787
80885
|
if (raw === ":memory:" || raw.startsWith("file:")) return null;
|
|
80788
|
-
return resolve14(
|
|
80886
|
+
return resolve14(dirname17(configPath), raw);
|
|
80789
80887
|
}
|
|
80790
80888
|
function deleteDatabaseFiles(targetConfigPath) {
|
|
80791
80889
|
const sqliteFile = sqliteFileForConfig(targetConfigPath);
|
|
80792
80890
|
unlinkSync5(targetConfigPath);
|
|
80793
80891
|
let deletedDbFile = null;
|
|
80794
|
-
if (sqliteFile &&
|
|
80892
|
+
if (sqliteFile && existsSync31(sqliteFile)) {
|
|
80795
80893
|
unlinkSync5(sqliteFile);
|
|
80796
80894
|
deletedDbFile = sqliteFile;
|
|
80797
80895
|
for (const suffix of ["-wal", "-shm", "-journal"]) {
|
|
80798
80896
|
const sidecar = sqliteFile + suffix;
|
|
80799
|
-
if (
|
|
80897
|
+
if (existsSync31(sidecar)) unlinkSync5(sidecar);
|
|
80800
80898
|
}
|
|
80801
80899
|
}
|
|
80802
80900
|
return { deletedConfig: basename13(targetConfigPath), deletedDbFile };
|
|
@@ -80830,7 +80928,7 @@ async function handleDatabasesRoutes(req, res, ctx, deps) {
|
|
|
80830
80928
|
return true;
|
|
80831
80929
|
}
|
|
80832
80930
|
const newPath = resolve15(body.path);
|
|
80833
|
-
if (!
|
|
80931
|
+
if (!existsSync32(newPath)) {
|
|
80834
80932
|
sendJson(res, { error: `Config not found: ${newPath}` }, 400);
|
|
80835
80933
|
return true;
|
|
80836
80934
|
}
|
|
@@ -80936,8 +81034,8 @@ async function handleDatabasesRoutes(req, res, ctx, deps) {
|
|
|
80936
81034
|
// src/gui/server.ts
|
|
80937
81035
|
init_user_config();
|
|
80938
81036
|
function resolveDefaultGuiAssetsDir() {
|
|
80939
|
-
const bundleSibling = process.argv[1] ? resolve16(
|
|
80940
|
-
if (bundleSibling &&
|
|
81037
|
+
const bundleSibling = process.argv[1] ? resolve16(dirname18(process.argv[1]), "gui-assets") : null;
|
|
81038
|
+
if (bundleSibling && existsSync33(bundleSibling)) return bundleSibling;
|
|
80941
81039
|
return resolve16(process.cwd(), "dist", "gui-assets");
|
|
80942
81040
|
}
|
|
80943
81041
|
function sendText(res, body, status = 200, contentType = "text/plain; charset=utf-8") {
|
|
@@ -80994,7 +81092,7 @@ async function startGuiServer(options) {
|
|
|
80994
81092
|
const sessionId = crypto.randomUUID();
|
|
80995
81093
|
let updateService = null;
|
|
80996
81094
|
let activeRef = bootConfigPath && bootOutputDir ? await openConfig(bootConfigPath, bootOutputDir, autoRender, options.realtimeWatchdogMs) : null;
|
|
80997
|
-
const latticeRoot = (bootConfigPath ? findLatticeRoot(
|
|
81095
|
+
const latticeRoot = (bootConfigPath ? findLatticeRoot(dirname18(bootConfigPath)) : null) ?? (options.latticeRoot ? resolve16(options.latticeRoot) : null);
|
|
80998
81096
|
let currentWorkspaceId = null;
|
|
80999
81097
|
if (latticeRoot && bootConfigPath) {
|
|
81000
81098
|
const launched = listWorkspaces(latticeRoot).find(
|
|
@@ -81348,7 +81446,7 @@ async function startGuiServer(options) {
|
|
|
81348
81446
|
createJunction: (otherTable) => createFileJunction(active, otherTable, sessionId),
|
|
81349
81447
|
createEntity: (entity, columns) => createUserEntity(active, entity, columns, sessionId),
|
|
81350
81448
|
aggressiveness: getAggressiveness(),
|
|
81351
|
-
latticeRoot:
|
|
81449
|
+
latticeRoot: dirname18(active.configPath),
|
|
81352
81450
|
configPath: active.configPath,
|
|
81353
81451
|
outputDir: active.outputDir,
|
|
81354
81452
|
sessionId,
|
|
@@ -81373,7 +81471,7 @@ async function startGuiServer(options) {
|
|
|
81373
81471
|
createJunction: (otherTable) => createFileJunction(active, otherTable, sessionId),
|
|
81374
81472
|
createEntity: (entity, columns) => createUserEntity(active, entity, columns, sessionId),
|
|
81375
81473
|
aggressiveness: getAggressiveness(),
|
|
81376
|
-
latticeRoot:
|
|
81474
|
+
latticeRoot: dirname18(active.configPath),
|
|
81377
81475
|
configPath: active.configPath,
|
|
81378
81476
|
outputDir: active.outputDir,
|
|
81379
81477
|
sessionId,
|
|
@@ -81384,6 +81482,7 @@ async function startGuiServer(options) {
|
|
|
81384
81482
|
return await dispatchSourcesRoute(req2, res2, {
|
|
81385
81483
|
db: active.db,
|
|
81386
81484
|
ingestFile: (p3) => ingestLocalFile(ingestCtx, mctx, p3, false),
|
|
81485
|
+
configPath: active.configPath,
|
|
81387
81486
|
pathname,
|
|
81388
81487
|
method
|
|
81389
81488
|
});
|
|
@@ -81399,7 +81498,7 @@ async function startGuiServer(options) {
|
|
|
81399
81498
|
return await dispatchImportRoute(req2, res2, {
|
|
81400
81499
|
db: active.db,
|
|
81401
81500
|
configPath: active.configPath,
|
|
81402
|
-
latticeRoot:
|
|
81501
|
+
latticeRoot: dirname18(active.configPath),
|
|
81403
81502
|
validTables: active.validTables,
|
|
81404
81503
|
softDeletable: active.softDeletable
|
|
81405
81504
|
});
|
|
@@ -81428,7 +81527,7 @@ async function startGuiServer(options) {
|
|
|
81428
81527
|
if (!pathname.startsWith("/api/files/")) return false;
|
|
81429
81528
|
return await dispatchFilesRoute(req2, res2, {
|
|
81430
81529
|
db: active.db,
|
|
81431
|
-
latticeRoot:
|
|
81530
|
+
latticeRoot: dirname18(active.configPath),
|
|
81432
81531
|
configPath: active.configPath,
|
|
81433
81532
|
pathname,
|
|
81434
81533
|
method
|
|
@@ -81921,7 +82020,7 @@ function printHelp() {
|
|
|
81921
82020
|
);
|
|
81922
82021
|
}
|
|
81923
82022
|
function getVersion() {
|
|
81924
|
-
if (true) return "4.3.
|
|
82023
|
+
if (true) return "4.3.2";
|
|
81925
82024
|
try {
|
|
81926
82025
|
const pkgPath = new URL("../package.json", import.meta.url).pathname;
|
|
81927
82026
|
const pkg = JSON.parse(readFileSync26(pkgPath, "utf-8"));
|
|
@@ -81935,7 +82034,7 @@ function printVersion() {
|
|
|
81935
82034
|
}
|
|
81936
82035
|
function getGuiAssetsDir() {
|
|
81937
82036
|
const fromBundle = new URL("./gui-assets", import.meta.url).pathname;
|
|
81938
|
-
if (
|
|
82037
|
+
if (existsSync34(fromBundle)) return fromBundle;
|
|
81939
82038
|
return new URL("../dist/gui-assets", import.meta.url).pathname;
|
|
81940
82039
|
}
|
|
81941
82040
|
async function runUpdate() {
|
|
@@ -81979,7 +82078,7 @@ function runGenerate(args) {
|
|
|
81979
82078
|
console.error('Error: config must have an "entities" key');
|
|
81980
82079
|
process.exit(1);
|
|
81981
82080
|
}
|
|
81982
|
-
const configDir2 =
|
|
82081
|
+
const configDir2 = dirname19(configPath);
|
|
81983
82082
|
const outDir = resolve17(args.out);
|
|
81984
82083
|
try {
|
|
81985
82084
|
const result = generateAll({ config, configDir: configDir2, outDir, scaffold: args.scaffold });
|