latticesql 4.2.2 → 4.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/cli.js +357 -36
- package/dist/desktop-entry.js +76390 -0
- package/dist/index.cjs +378 -53
- package/dist/index.d.cts +76 -1
- package/dist/index.d.ts +76 -1
- package/dist/index.js +358 -35
- package/docs/desktop.md +75 -0
- package/package.json +6 -1
package/dist/index.cjs
CHANGED
|
@@ -249,7 +249,7 @@ var init_manifest = __esm({
|
|
|
249
249
|
import_node_path2 = require("path");
|
|
250
250
|
import_node_fs2 = require("fs");
|
|
251
251
|
init_writer();
|
|
252
|
-
TEMPLATE_VERSION =
|
|
252
|
+
TEMPLATE_VERSION = 3;
|
|
253
253
|
}
|
|
254
254
|
});
|
|
255
255
|
|
|
@@ -729,14 +729,177 @@ var init_sqlite = __esm({
|
|
|
729
729
|
}
|
|
730
730
|
});
|
|
731
731
|
|
|
732
|
+
// src/db/sqlite-deno.ts
|
|
733
|
+
function runtimeRequire2() {
|
|
734
|
+
const importMetaUrl = import_meta2.url;
|
|
735
|
+
return importMetaUrl ? (0, import_node_module2.createRequire)(importMetaUrl) : require;
|
|
736
|
+
}
|
|
737
|
+
function loadNodeSqlite() {
|
|
738
|
+
if (_ctor2) return _ctor2;
|
|
739
|
+
const mod = runtimeRequire2()("node:sqlite");
|
|
740
|
+
if (!mod.DatabaseSync) {
|
|
741
|
+
throw new Error(
|
|
742
|
+
"node:sqlite is unavailable in this runtime \u2014 cannot open the Deno SQLite adapter"
|
|
743
|
+
);
|
|
744
|
+
}
|
|
745
|
+
_ctor2 = mod.DatabaseSync;
|
|
746
|
+
return _ctor2;
|
|
747
|
+
}
|
|
748
|
+
var import_node_module2, import_meta2, _ctor2, DenoSqliteAdapter;
|
|
749
|
+
var init_sqlite_deno = __esm({
|
|
750
|
+
"src/db/sqlite-deno.ts"() {
|
|
751
|
+
"use strict";
|
|
752
|
+
import_node_module2 = require("module");
|
|
753
|
+
import_meta2 = {};
|
|
754
|
+
_ctor2 = null;
|
|
755
|
+
DenoSqliteAdapter = class {
|
|
756
|
+
dialect = "sqlite";
|
|
757
|
+
_db = null;
|
|
758
|
+
_path;
|
|
759
|
+
_wal;
|
|
760
|
+
_busyTimeout;
|
|
761
|
+
constructor(path3, options) {
|
|
762
|
+
this._path = path3;
|
|
763
|
+
this._wal = options?.wal ?? true;
|
|
764
|
+
this._busyTimeout = options?.busyTimeout ?? 5e3;
|
|
765
|
+
}
|
|
766
|
+
get db() {
|
|
767
|
+
if (!this._db) throw new Error("DenoSqliteAdapter: not open \u2014 call open() first");
|
|
768
|
+
return this._db;
|
|
769
|
+
}
|
|
770
|
+
open() {
|
|
771
|
+
const Ctor = loadNodeSqlite();
|
|
772
|
+
this._db = new Ctor(this._path);
|
|
773
|
+
this._db.exec(`PRAGMA busy_timeout = ${this._busyTimeout.toString()}`);
|
|
774
|
+
if (this._wal) {
|
|
775
|
+
this._db.exec("PRAGMA journal_mode = WAL");
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
close() {
|
|
779
|
+
this._db?.close();
|
|
780
|
+
this._db = null;
|
|
781
|
+
}
|
|
782
|
+
run(sql, params = []) {
|
|
783
|
+
this.db.prepare(sql).run(...params);
|
|
784
|
+
}
|
|
785
|
+
get(sql, params = []) {
|
|
786
|
+
return this.db.prepare(sql).get(...params);
|
|
787
|
+
}
|
|
788
|
+
all(sql, params = []) {
|
|
789
|
+
return this.db.prepare(sql).all(...params);
|
|
790
|
+
}
|
|
791
|
+
prepare(sql) {
|
|
792
|
+
const stmt = this.db.prepare(sql);
|
|
793
|
+
return {
|
|
794
|
+
run: (...params) => {
|
|
795
|
+
const info = stmt.run(...params);
|
|
796
|
+
return {
|
|
797
|
+
changes: Number(info.changes),
|
|
798
|
+
lastInsertRowid: info.lastInsertRowid
|
|
799
|
+
};
|
|
800
|
+
},
|
|
801
|
+
get: (...params) => stmt.get(...params),
|
|
802
|
+
all: (...params) => stmt.all(...params)
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
introspectColumns(table) {
|
|
806
|
+
const rows = this.all(`PRAGMA table_info("${table}")`);
|
|
807
|
+
return rows.map((r6) => r6.name);
|
|
808
|
+
}
|
|
809
|
+
/** Mirror of SQLiteAdapter.addColumn — SQLite ALTER quirks are binding-agnostic. */
|
|
810
|
+
addColumn(table, column, typeSpec) {
|
|
811
|
+
const upperType = typeSpec.toUpperCase();
|
|
812
|
+
if (upperType.includes("PRIMARY KEY")) return;
|
|
813
|
+
const hasNonConstantDefault = upperType.includes("CURRENT_TIMESTAMP") || /DATETIME\s*\(\s*'NOW'\s*\)/i.test(typeSpec) || upperType.includes("RANDOM()");
|
|
814
|
+
if (hasNonConstantDefault) {
|
|
815
|
+
const safeType = typeSpec.replace(/\bNOT\s+NULL\b/gi, "").replace(/\bDEFAULT\s+\(?\s*CURRENT_TIMESTAMP\s*\)?/gi, "").replace(/\bDEFAULT\s+\(?\s*datetime\([^)]*\)\s*\)?/gi, "").replace(/\bDEFAULT\s+\(?\s*RANDOM\(\)\s*\)?/gi, "").replace(/\s+/g, " ").trim();
|
|
816
|
+
this.run(`ALTER TABLE "${table}" ADD COLUMN "${column}" ${safeType || "TEXT"}`);
|
|
817
|
+
this.run(`UPDATE "${table}" SET "${column}" = CURRENT_TIMESTAMP WHERE "${column}" IS NULL`);
|
|
818
|
+
} else {
|
|
819
|
+
this.run(`ALTER TABLE "${table}" ADD COLUMN "${column}" ${typeSpec}`);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* O(1) watch-loop change-probe — same composition as SQLiteAdapter, but
|
|
824
|
+
* `data_version` is read with a plain prepared statement because node:sqlite
|
|
825
|
+
* has no `.pragma(name, { simple: true })` scalar helper.
|
|
826
|
+
*/
|
|
827
|
+
changeProbe() {
|
|
828
|
+
const dataVersion = this.db.prepare("PRAGMA data_version").get().data_version;
|
|
829
|
+
const totalChanges = this.db.prepare("SELECT total_changes() AS n").get().n;
|
|
830
|
+
return `${String(dataVersion)}:${String(totalChanges)}`;
|
|
831
|
+
}
|
|
832
|
+
// ── Async surface (sync under the hood; mirrors SQLiteAdapter) ──────────
|
|
833
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
834
|
+
async runAsync(sql, params) {
|
|
835
|
+
this.run(sql, params);
|
|
836
|
+
}
|
|
837
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
838
|
+
async getAsync(sql, params) {
|
|
839
|
+
return this.get(sql, params);
|
|
840
|
+
}
|
|
841
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
842
|
+
async allAsync(sql, params) {
|
|
843
|
+
return this.all(sql, params);
|
|
844
|
+
}
|
|
845
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
846
|
+
async introspectColumnsAsync(table) {
|
|
847
|
+
return this.introspectColumns(table);
|
|
848
|
+
}
|
|
849
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
850
|
+
async introspectAllColumns(tables) {
|
|
851
|
+
const map = /* @__PURE__ */ new Map();
|
|
852
|
+
for (const t8 of tables) {
|
|
853
|
+
try {
|
|
854
|
+
const cols = this.introspectColumns(t8);
|
|
855
|
+
if (cols.length > 0) map.set(t8, new Set(cols));
|
|
856
|
+
} catch {
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return map;
|
|
860
|
+
}
|
|
861
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
862
|
+
async addColumnAsync(table, column, typeSpec) {
|
|
863
|
+
this.addColumn(table, column, typeSpec);
|
|
864
|
+
}
|
|
865
|
+
/** BEGIN/COMMIT around an awaited fn; ROLLBACK on throw. Mirror of SQLiteAdapter. */
|
|
866
|
+
async withClient(fn) {
|
|
867
|
+
const dbRef = this.db;
|
|
868
|
+
const getSync = this.get.bind(this);
|
|
869
|
+
const allSync = this.all.bind(this);
|
|
870
|
+
const tx = {
|
|
871
|
+
run: (sql, params) => {
|
|
872
|
+
const info = dbRef.prepare(sql).run(...params ?? []);
|
|
873
|
+
return Promise.resolve({ changes: Number(info.changes) });
|
|
874
|
+
},
|
|
875
|
+
get: (sql, params) => Promise.resolve(getSync(sql, params ?? [])),
|
|
876
|
+
all: (sql, params) => Promise.resolve(allSync(sql, params ?? []))
|
|
877
|
+
};
|
|
878
|
+
this.run("BEGIN");
|
|
879
|
+
try {
|
|
880
|
+
const result = await fn(tx);
|
|
881
|
+
this.run("COMMIT");
|
|
882
|
+
return result;
|
|
883
|
+
} catch (err) {
|
|
884
|
+
try {
|
|
885
|
+
this.run("ROLLBACK");
|
|
886
|
+
} catch {
|
|
887
|
+
}
|
|
888
|
+
throw err;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
}
|
|
893
|
+
});
|
|
894
|
+
|
|
732
895
|
// src/db/postgres.ts
|
|
733
896
|
function moduleContext() {
|
|
734
897
|
if (_moduleContext) return _moduleContext;
|
|
735
|
-
const importMetaUrl =
|
|
898
|
+
const importMetaUrl = import_meta3.url;
|
|
736
899
|
if (importMetaUrl) {
|
|
737
900
|
_moduleContext = {
|
|
738
901
|
dir: import_node_path4.default.dirname((0, import_node_url.fileURLToPath)(importMetaUrl)),
|
|
739
|
-
require: (0,
|
|
902
|
+
require: (0, import_node_module3.createRequire)(importMetaUrl)
|
|
740
903
|
};
|
|
741
904
|
} else {
|
|
742
905
|
_moduleContext = { dir: __dirname, require };
|
|
@@ -994,14 +1157,14 @@ function rewriteParams(sql) {
|
|
|
994
1157
|
function rewrite(sql) {
|
|
995
1158
|
return rewriteParams(translateDialect(sql));
|
|
996
1159
|
}
|
|
997
|
-
var import_node_path4, import_node_url,
|
|
1160
|
+
var import_node_path4, import_node_url, import_node_module3, import_meta3, _moduleContext, SYNC_NOT_SUPPORTED_MSG, PostgresAdapter, POSTGRES_POLYFILLS;
|
|
998
1161
|
var init_postgres = __esm({
|
|
999
1162
|
"src/db/postgres.ts"() {
|
|
1000
1163
|
"use strict";
|
|
1001
1164
|
import_node_path4 = __toESM(require("path"), 1);
|
|
1002
1165
|
import_node_url = require("url");
|
|
1003
|
-
|
|
1004
|
-
|
|
1166
|
+
import_node_module3 = require("module");
|
|
1167
|
+
import_meta3 = {};
|
|
1005
1168
|
_moduleContext = null;
|
|
1006
1169
|
SYNC_NOT_SUPPORTED_MSG = "PostgresAdapter: synchronous adapter methods (run/get/all/prepare/introspectColumns/addColumn) are no longer supported on Postgres as of latticesql 1.10.0. Use the async surface (runAsync/getAsync/allAsync/prepareAsync/introspectColumnsAsync/addColumnAsync/withClient) instead. Lattice core methods (Lattice.query, .insert, .update, .render, etc.) already route through the async surface \u2014 only consumer code that escapes into adapter.run/get/all directly needs migrating.";
|
|
1007
1170
|
PostgresAdapter = class {
|
|
@@ -3446,6 +3609,64 @@ function cleanupEntityContexts(outputDir, entityContexts, currentSlugsByTable, m
|
|
|
3446
3609
|
warnings: []
|
|
3447
3610
|
};
|
|
3448
3611
|
if (manifest === null) return result;
|
|
3612
|
+
if (options.removeOrphanedDirectories !== false) {
|
|
3613
|
+
for (const [table, entry] of Object.entries(manifest.entityContexts)) {
|
|
3614
|
+
if (entityContexts.has(table)) continue;
|
|
3615
|
+
const directoryRoot = entry.directoryRoot;
|
|
3616
|
+
const rootPath = (0, import_node_path5.join)(outputDir, directoryRoot);
|
|
3617
|
+
if (!(0, import_node_fs3.existsSync)(rootPath)) continue;
|
|
3618
|
+
const globalProtected = new Set(options.protectedFiles ?? []);
|
|
3619
|
+
for (const [slug, files] of Object.entries(entry.entities)) {
|
|
3620
|
+
const entityDir = (0, import_node_path5.join)(rootPath, slug);
|
|
3621
|
+
if (!(0, import_node_fs3.existsSync)(entityDir)) continue;
|
|
3622
|
+
for (const filename of entityFileNames(files)) {
|
|
3623
|
+
if (globalProtected.has(filename)) continue;
|
|
3624
|
+
const filePath = (0, import_node_path5.join)(entityDir, filename);
|
|
3625
|
+
if (!(0, import_node_fs3.existsSync)(filePath)) continue;
|
|
3626
|
+
if (!options.dryRun) (0, import_node_fs3.unlinkSync)(filePath);
|
|
3627
|
+
options.onOrphan?.(filePath, "file");
|
|
3628
|
+
result.filesRemoved.push(filePath);
|
|
3629
|
+
}
|
|
3630
|
+
let remaining;
|
|
3631
|
+
try {
|
|
3632
|
+
remaining = (0, import_node_fs3.existsSync)(entityDir) ? (0, import_node_fs3.readdirSync)(entityDir) : [];
|
|
3633
|
+
} catch {
|
|
3634
|
+
remaining = [];
|
|
3635
|
+
}
|
|
3636
|
+
if (remaining.length === 0) {
|
|
3637
|
+
if (!options.dryRun) {
|
|
3638
|
+
try {
|
|
3639
|
+
(0, import_node_fs3.rmdirSync)(entityDir);
|
|
3640
|
+
} catch {
|
|
3641
|
+
}
|
|
3642
|
+
}
|
|
3643
|
+
options.onOrphan?.(entityDir, "directory");
|
|
3644
|
+
result.directoriesRemoved.push(entityDir);
|
|
3645
|
+
} else {
|
|
3646
|
+
result.directoriesSkipped.push(entityDir);
|
|
3647
|
+
result.warnings.push(
|
|
3648
|
+
`${entityDir}: left in place (contains user files: ${remaining.join(", ")})`
|
|
3649
|
+
);
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
let rootRemaining;
|
|
3653
|
+
try {
|
|
3654
|
+
rootRemaining = (0, import_node_fs3.existsSync)(rootPath) ? (0, import_node_fs3.readdirSync)(rootPath) : [];
|
|
3655
|
+
} catch {
|
|
3656
|
+
rootRemaining = [];
|
|
3657
|
+
}
|
|
3658
|
+
if (rootRemaining.length === 0) {
|
|
3659
|
+
if (!options.dryRun) {
|
|
3660
|
+
try {
|
|
3661
|
+
(0, import_node_fs3.rmdirSync)(rootPath);
|
|
3662
|
+
} catch {
|
|
3663
|
+
}
|
|
3664
|
+
}
|
|
3665
|
+
options.onOrphan?.(rootPath, "directory");
|
|
3666
|
+
result.directoriesRemoved.push(rootPath);
|
|
3667
|
+
}
|
|
3668
|
+
}
|
|
3669
|
+
}
|
|
3449
3670
|
for (const [table, def] of entityContexts) {
|
|
3450
3671
|
const entry = manifest.entityContexts[table];
|
|
3451
3672
|
if (!entry) continue;
|
|
@@ -3945,7 +4166,8 @@ var init_engine = __esm({
|
|
|
3945
4166
|
const currentSlugsByTable = /* @__PURE__ */ new Map();
|
|
3946
4167
|
for (const [table, def] of entityContexts) {
|
|
3947
4168
|
const rows = await this._schema.queryTable(this._adapter, table, this._schema.readRel);
|
|
3948
|
-
const
|
|
4169
|
+
const entityPk = this._schema.getPrimaryKey(table)[0] ?? "id";
|
|
4170
|
+
const slugs = new Set(_RenderEngine._disambiguateSlugs(rows, def.slug, entityPk));
|
|
3949
4171
|
currentSlugsByTable.set(table, slugs);
|
|
3950
4172
|
}
|
|
3951
4173
|
return cleanupEntityContexts(
|
|
@@ -3994,6 +4216,71 @@ var init_engine = __esm({
|
|
|
3994
4216
|
static _normKey(v2) {
|
|
3995
4217
|
return String(v2);
|
|
3996
4218
|
}
|
|
4219
|
+
/**
|
|
4220
|
+
* Sanitize and validate ONE base slug.
|
|
4221
|
+
*
|
|
4222
|
+
* Replaces non-ASCII whitespace (e.g. the macOS narrow no-break space U+202F
|
|
4223
|
+
* that shows up in screenshot filenames) with a regular space, strips control
|
|
4224
|
+
* characters, then rejects any slug that still contains a character outside the
|
|
4225
|
+
* allowed set (the path-traversal guard). Throws on an invalid slug — never
|
|
4226
|
+
* silently rewrites it.
|
|
4227
|
+
*/
|
|
4228
|
+
static _sanitizeSlug(rawSlug) {
|
|
4229
|
+
const slug = rawSlug.replace(/[\u00A0\u2000-\u200B\u202F\u205F\u3000]/g, " ").replace(/[\u0000-\u001F\u007F]/g, "");
|
|
4230
|
+
if (/[^a-zA-Z0-9.\-_ @(),#&'+:;!~[\]]/.test(slug)) {
|
|
4231
|
+
throw new Error(`Invalid slug "${slug}": contains characters outside the allowed set`);
|
|
4232
|
+
}
|
|
4233
|
+
return slug;
|
|
4234
|
+
}
|
|
4235
|
+
/**
|
|
4236
|
+
* Disambiguate per-row slugs so two rows that produce the SAME base slug do not
|
|
4237
|
+
* write to (and clobber) the same directory.
|
|
4238
|
+
*
|
|
4239
|
+
* Returns one final slug per row, in the SAME order as `rows`. A base slug used
|
|
4240
|
+
* by exactly one row is returned unchanged (no churn for the common case). When
|
|
4241
|
+
* a base slug is shared by >1 row, EVERY colliding row gets a short, stable
|
|
4242
|
+
* suffix derived from its primary key (`<base>-<pk8>`), so the result is
|
|
4243
|
+
* order-independent: the same row gets the same slug on every render regardless
|
|
4244
|
+
* of row order. The suffix lengthens only if two rows' 8-char PK prefixes still
|
|
4245
|
+
* collide (e.g. shared prefix), guaranteeing uniqueness without changing the
|
|
4246
|
+
* common-case output. Slugs are sanitized + path-traversal-validated via
|
|
4247
|
+
* {@link _sanitizeSlug}; `def.slug` itself is never modified.
|
|
4248
|
+
*/
|
|
4249
|
+
static _disambiguateSlugs(rows, slugFn, pkCol) {
|
|
4250
|
+
const baseSlugs = rows.map((row) => _RenderEngine._sanitizeSlug(slugFn(row)));
|
|
4251
|
+
const byBase = /* @__PURE__ */ new Map();
|
|
4252
|
+
for (let i6 = 0; i6 < baseSlugs.length; i6++) {
|
|
4253
|
+
const base = baseSlugs[i6];
|
|
4254
|
+
const bucket = byBase.get(base);
|
|
4255
|
+
if (bucket) bucket.push(i6);
|
|
4256
|
+
else byBase.set(base, [i6]);
|
|
4257
|
+
}
|
|
4258
|
+
const final = baseSlugs.map(() => "");
|
|
4259
|
+
const pkOf = (i6) => {
|
|
4260
|
+
const v2 = rows[i6]?.[pkCol];
|
|
4261
|
+
let s2;
|
|
4262
|
+
if (v2 == null) s2 = "";
|
|
4263
|
+
else if (typeof v2 === "object") s2 = JSON.stringify(v2);
|
|
4264
|
+
else s2 = String(v2);
|
|
4265
|
+
return _RenderEngine._sanitizeSlug(s2).replace(/[ /\\]/g, "");
|
|
4266
|
+
};
|
|
4267
|
+
for (const [base, indices] of byBase) {
|
|
4268
|
+
if (indices.length === 1) {
|
|
4269
|
+
final[indices[0]] = base;
|
|
4270
|
+
continue;
|
|
4271
|
+
}
|
|
4272
|
+
const pks = indices.map(pkOf);
|
|
4273
|
+
const maxLen = Math.max(...pks.map((p3) => p3.length), 1);
|
|
4274
|
+
let len = 8;
|
|
4275
|
+
while (len < maxLen && new Set(pks.map((p3) => p3.slice(0, len))).size !== pks.length) {
|
|
4276
|
+
len += 4;
|
|
4277
|
+
}
|
|
4278
|
+
for (let k6 = 0; k6 < indices.length; k6++) {
|
|
4279
|
+
final[indices[k6]] = `${base}-${pks[k6].slice(0, len)}`;
|
|
4280
|
+
}
|
|
4281
|
+
}
|
|
4282
|
+
return final;
|
|
4283
|
+
}
|
|
3997
4284
|
/**
|
|
3998
4285
|
* Prefetch the batchable belongsTo sources for one entity-context table.
|
|
3999
4286
|
* For each (target+filters+softDelete) group, issue exactly ONE
|
|
@@ -4074,6 +4361,7 @@ var init_engine = __esm({
|
|
|
4074
4361
|
const baseRows = await this._schema.queryTable(this._adapter, table, this._schema.readRel);
|
|
4075
4362
|
const allRows = this._foldRows ? await this._foldRows(table, baseRows) : baseRows;
|
|
4076
4363
|
const directoryRoot = def.directoryRoot ?? table;
|
|
4364
|
+
const finalSlugs = _RenderEngine._disambiguateSlugs(allRows, def.slug, entityPk);
|
|
4077
4365
|
const belongsToBatches = await this._prefetchBelongsToBatches(
|
|
4078
4366
|
def,
|
|
4079
4367
|
allRows,
|
|
@@ -4115,11 +4403,7 @@ var init_engine = __esm({
|
|
|
4115
4403
|
if (i6 > 0 && i6 % YIELD_EVERY_ENTITIES === 0) {
|
|
4116
4404
|
await new Promise((r6) => setImmediate(r6));
|
|
4117
4405
|
}
|
|
4118
|
-
const
|
|
4119
|
-
const slug = rawSlug.replace(/[\u00A0\u2000-\u200B\u202F\u205F\u3000]/g, " ").replace(/[\u0000-\u001F\u007F]/g, "");
|
|
4120
|
-
if (/[^a-zA-Z0-9.\-_ @(),#&'+:;!~[\]]/.test(slug)) {
|
|
4121
|
-
throw new Error(`Invalid slug "${slug}": contains characters outside the allowed set`);
|
|
4122
|
-
}
|
|
4406
|
+
const slug = finalSlugs[i6];
|
|
4123
4407
|
const entityDir = def.directory ? (0, import_node_path6.join)(outputDir, def.directory(entityRow)) : (0, import_node_path6.join)(outputDir, directoryRoot, slug);
|
|
4124
4408
|
const resolvedDir = (0, import_node_path6.resolve)(entityDir);
|
|
4125
4409
|
const resolvedBase = (0, import_node_path6.resolve)(outputDir);
|
|
@@ -9807,6 +10091,9 @@ function buildAdapter(dbPath, options) {
|
|
|
9807
10091
|
const adapterOpts = {};
|
|
9808
10092
|
if (options.wal !== void 0) adapterOpts.wal = options.wal;
|
|
9809
10093
|
if (options.busyTimeout !== void 0) adapterOpts.busyTimeout = options.busyTimeout;
|
|
10094
|
+
if (typeof globalThis.Deno !== "undefined") {
|
|
10095
|
+
return new DenoSqliteAdapter(sqlitePath, adapterOpts);
|
|
10096
|
+
}
|
|
9810
10097
|
return new SQLiteAdapter(sqlitePath, adapterOpts);
|
|
9811
10098
|
}
|
|
9812
10099
|
function _resolveTemplateName(render) {
|
|
@@ -9828,6 +10115,7 @@ var init_lattice = __esm({
|
|
|
9828
10115
|
import_node_fs12 = require("fs");
|
|
9829
10116
|
init_adapter();
|
|
9830
10117
|
init_sqlite();
|
|
10118
|
+
init_sqlite_deno();
|
|
9831
10119
|
init_postgres();
|
|
9832
10120
|
init_pk();
|
|
9833
10121
|
init_manager();
|
|
@@ -52363,11 +52651,11 @@ var init_table_policy = __esm({
|
|
|
52363
52651
|
});
|
|
52364
52652
|
|
|
52365
52653
|
// src/ai/llm-client.ts
|
|
52366
|
-
var
|
|
52654
|
+
var import_node_module4, DEFAULT_MODEL, CHEAPEST_MODEL;
|
|
52367
52655
|
var init_llm_client = __esm({
|
|
52368
52656
|
"src/ai/llm-client.ts"() {
|
|
52369
52657
|
"use strict";
|
|
52370
|
-
|
|
52658
|
+
import_node_module4 = require("module");
|
|
52371
52659
|
DEFAULT_MODEL = "claude-haiku-4-5";
|
|
52372
52660
|
CHEAPEST_MODEL = "claude-haiku-4-5";
|
|
52373
52661
|
}
|
|
@@ -52779,8 +53067,8 @@ async function sniffMime(body) {
|
|
|
52779
53067
|
async function renderViaPlaywright(url, timeoutMs, warnIfMissing = false) {
|
|
52780
53068
|
let chromium;
|
|
52781
53069
|
try {
|
|
52782
|
-
const importMetaUrl =
|
|
52783
|
-
const req = importMetaUrl ? (0,
|
|
53070
|
+
const importMetaUrl = import_meta4.url;
|
|
53071
|
+
const req = importMetaUrl ? (0, import_node_module5.createRequire)(importMetaUrl) : require;
|
|
52784
53072
|
const pw = req("playwright");
|
|
52785
53073
|
chromium = pw.chromium;
|
|
52786
53074
|
} catch {
|
|
@@ -52804,16 +53092,16 @@ async function renderViaPlaywright(url, timeoutMs, warnIfMissing = false) {
|
|
|
52804
53092
|
if (browser) await browser.close().catch(() => void 0);
|
|
52805
53093
|
}
|
|
52806
53094
|
}
|
|
52807
|
-
var import_jsdom, import_readability, import_node_path27,
|
|
53095
|
+
var import_jsdom, import_readability, import_node_path27, import_node_module5, import_meta4, DEFAULT_MAX_BYTES2, DEFAULT_TIMEOUT_MS, DEFAULT_UA, DOMAIN_EXTRACTORS, warnedPlaywrightMissing;
|
|
52808
53096
|
var init_crawl = __esm({
|
|
52809
53097
|
"src/ai/crawl.ts"() {
|
|
52810
53098
|
"use strict";
|
|
52811
53099
|
import_jsdom = require("jsdom");
|
|
52812
53100
|
import_readability = require("@mozilla/readability");
|
|
52813
53101
|
import_node_path27 = require("path");
|
|
52814
|
-
|
|
53102
|
+
import_node_module5 = require("module");
|
|
52815
53103
|
init_url_safety();
|
|
52816
|
-
|
|
53104
|
+
import_meta4 = {};
|
|
52817
53105
|
DEFAULT_MAX_BYTES2 = 25 * 1024 * 1024;
|
|
52818
53106
|
DEFAULT_TIMEOUT_MS = 3e4;
|
|
52819
53107
|
DEFAULT_UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36";
|
|
@@ -53985,9 +54273,6 @@ async function resolveClaudeAuth(db) {
|
|
|
53985
54273
|
const apiKey = await resolveAnthropicKey(db);
|
|
53986
54274
|
return apiKey ? { apiKey } : null;
|
|
53987
54275
|
}
|
|
53988
|
-
async function hasClaudeAuth(db) {
|
|
53989
|
-
return Boolean(await readMachineCredential(db, CLAUDE_OAUTH_KIND)) || await hasCredential(db, "anthropic", "ANTHROPIC_API_KEY");
|
|
53990
|
-
}
|
|
53991
54276
|
async function claudeAuthKind(db) {
|
|
53992
54277
|
if (await readMachineCredential(db, CLAUDE_OAUTH_KIND)) return "oauth";
|
|
53993
54278
|
if (await hasCredential(db, "anthropic", "ANTHROPIC_API_KEY")) return "key";
|
|
@@ -54015,7 +54300,6 @@ async function dispatchAssistantRoute(req, res, ctx) {
|
|
|
54015
54300
|
hasAnthropicKey,
|
|
54016
54301
|
hasOpenaiKey,
|
|
54017
54302
|
hasElevenlabsKey,
|
|
54018
|
-
hasClaudeAuth: await hasClaudeAuth(db),
|
|
54019
54303
|
claudeAuthKind: await claudeAuthKind(db),
|
|
54020
54304
|
hasVoiceKey: voice !== null,
|
|
54021
54305
|
sttProvider: voice?.provider ?? null,
|
|
@@ -54143,13 +54427,17 @@ async function dispatchAssistantRoute(req, res, ctx) {
|
|
|
54143
54427
|
const verifier = generatePkceVerifier();
|
|
54144
54428
|
const state2 = generateState();
|
|
54145
54429
|
const cookieOpts = "HttpOnly; Path=/; Max-Age=600; SameSite=Lax";
|
|
54146
|
-
|
|
54147
|
-
|
|
54148
|
-
|
|
54149
|
-
|
|
54150
|
-
|
|
54151
|
-
|
|
54152
|
-
|
|
54430
|
+
const setCookie = [
|
|
54431
|
+
`lat_oauth_verifier=${verifier}; ${cookieOpts}`,
|
|
54432
|
+
`lat_oauth_state=${state2}; ${cookieOpts}`
|
|
54433
|
+
];
|
|
54434
|
+
const authorizeUrl = buildAuthorizeUrl(cfg, state2, pkceChallengeFor(verifier));
|
|
54435
|
+
if ((req.headers.accept ?? "").includes("application/json")) {
|
|
54436
|
+
res.writeHead(200, { "Content-Type": "application/json", "Set-Cookie": setCookie });
|
|
54437
|
+
res.end(JSON.stringify({ authorizeUrl }));
|
|
54438
|
+
return true;
|
|
54439
|
+
}
|
|
54440
|
+
res.writeHead(302, { Location: authorizeUrl, "Set-Cookie": setCookie });
|
|
54153
54441
|
res.end();
|
|
54154
54442
|
return true;
|
|
54155
54443
|
}
|
|
@@ -54725,7 +55013,7 @@ function findDocsDir() {
|
|
|
54725
55013
|
if (_docsDir !== void 0) return _docsDir;
|
|
54726
55014
|
let dir;
|
|
54727
55015
|
try {
|
|
54728
|
-
dir = (0, import_node_path29.dirname)((0, import_node_url2.fileURLToPath)(
|
|
55016
|
+
dir = (0, import_node_path29.dirname)((0, import_node_url2.fileURLToPath)(import_meta7.url));
|
|
54729
55017
|
} catch {
|
|
54730
55018
|
dir = process.cwd();
|
|
54731
55019
|
}
|
|
@@ -54820,14 +55108,14 @@ function searchLatticeDocs(query, limit = 4) {
|
|
|
54820
55108
|
}))
|
|
54821
55109
|
};
|
|
54822
55110
|
}
|
|
54823
|
-
var import_node_fs27, import_node_path29, import_node_url2,
|
|
55111
|
+
var import_node_fs27, import_node_path29, import_node_url2, import_meta7, _docsDir, MAX_SECTION_CHARS, _cache;
|
|
54824
55112
|
var init_lattice_docs = __esm({
|
|
54825
55113
|
"src/gui/ai/lattice-docs.ts"() {
|
|
54826
55114
|
"use strict";
|
|
54827
55115
|
import_node_fs27 = require("fs");
|
|
54828
55116
|
import_node_path29 = require("path");
|
|
54829
55117
|
import_node_url2 = require("url");
|
|
54830
|
-
|
|
55118
|
+
import_meta7 = {};
|
|
54831
55119
|
MAX_SECTION_CHARS = 2400;
|
|
54832
55120
|
_cache = /* @__PURE__ */ new Map();
|
|
54833
55121
|
}
|
|
@@ -57694,8 +57982,8 @@ async function* runChat(opts) {
|
|
|
57694
57982
|
}
|
|
57695
57983
|
function loadSdk() {
|
|
57696
57984
|
if (!_sdk) {
|
|
57697
|
-
const importMetaUrl =
|
|
57698
|
-
const req = importMetaUrl ? (0,
|
|
57985
|
+
const importMetaUrl = import_meta8.url;
|
|
57986
|
+
const req = importMetaUrl ? (0, import_node_module8.createRequire)(importMetaUrl) : require;
|
|
57699
57987
|
try {
|
|
57700
57988
|
_sdk = req("@anthropic-ai/sdk");
|
|
57701
57989
|
} catch (err) {
|
|
@@ -57752,15 +58040,15 @@ function createAnthropicClient(auth) {
|
|
|
57752
58040
|
}
|
|
57753
58041
|
};
|
|
57754
58042
|
}
|
|
57755
|
-
var
|
|
58043
|
+
var import_node_module8, import_meta8, DEFAULT_MODEL2, MAX_TOOL_LOOPS, MAX_CONSECUTIVE_TOOL_FAILURES, MAX_TOKENS, MAX_TOOL_RESULT_CHARS, MAX_TOOL_RESULT_SKIP, MAX_TOOL_INPUT_CHARS, LIVE_TOOL_RESULT_CHARS, MAX_CONTEXT_RECOVERY_TRIMS, TRIMMED_PLACEHOLDER, BASE_SYSTEM_PROMPT, LOCAL_GUI_RECORD_RE, _sdk;
|
|
57756
58044
|
var init_chat = __esm({
|
|
57757
58045
|
"src/gui/ai/chat.ts"() {
|
|
57758
58046
|
"use strict";
|
|
57759
|
-
|
|
58047
|
+
import_node_module8 = require("module");
|
|
57760
58048
|
init_dispatch();
|
|
57761
58049
|
init_tools();
|
|
57762
58050
|
init_column_descriptions();
|
|
57763
|
-
|
|
58051
|
+
import_meta8 = {};
|
|
57764
58052
|
DEFAULT_MODEL2 = "claude-haiku-4-5";
|
|
57765
58053
|
MAX_TOOL_LOOPS = 16;
|
|
57766
58054
|
MAX_CONSECUTIVE_TOOL_FAILURES = 3;
|
|
@@ -57806,6 +58094,7 @@ __export(index_exports, {
|
|
|
57806
58094
|
DEFAULT_ENTRY_TYPES: () => DEFAULT_ENTRY_TYPES,
|
|
57807
58095
|
DEFAULT_MAX_NODES: () => DEFAULT_MAX_NODES,
|
|
57808
58096
|
DEFAULT_TYPE_ALIASES: () => DEFAULT_TYPE_ALIASES,
|
|
58097
|
+
DenoSqliteAdapter: () => DenoSqliteAdapter,
|
|
57809
58098
|
EMBEDDINGS_TABLE: () => EMBEDDINGS_TABLE,
|
|
57810
58099
|
EmbeddingDimensionMismatchError: () => EmbeddingDimensionMismatchError,
|
|
57811
58100
|
EmbeddingScanTooLargeError: () => EmbeddingScanTooLargeError,
|
|
@@ -58564,6 +58853,7 @@ async function autoUpdate(opts) {
|
|
|
58564
58853
|
|
|
58565
58854
|
// src/index.ts
|
|
58566
58855
|
init_sqlite();
|
|
58856
|
+
init_sqlite_deno();
|
|
58567
58857
|
init_postgres();
|
|
58568
58858
|
init_computed();
|
|
58569
58859
|
init_governance();
|
|
@@ -59886,10 +60176,10 @@ function isBetter(next, prev) {
|
|
|
59886
60176
|
}
|
|
59887
60177
|
|
|
59888
60178
|
// src/ai/vision.ts
|
|
59889
|
-
var
|
|
60179
|
+
var import_node_module6 = require("module");
|
|
59890
60180
|
var import_promises7 = require("fs/promises");
|
|
59891
60181
|
init_llm_client();
|
|
59892
|
-
var
|
|
60182
|
+
var import_meta5 = {};
|
|
59893
60183
|
var DEFAULT_PROMPT = "Describe this image for a knowledge base in 2-4 factual sentences: what it shows, any visible text, and notable details. No preamble.";
|
|
59894
60184
|
var MAX_DIM = 1568;
|
|
59895
60185
|
async function describeImage(auth, path3, opts = {}) {
|
|
@@ -59949,8 +60239,8 @@ function buildVisionAnthropicConfig(auth) {
|
|
|
59949
60239
|
}
|
|
59950
60240
|
function defaultSender(auth) {
|
|
59951
60241
|
return async (input) => {
|
|
59952
|
-
const importMetaUrl =
|
|
59953
|
-
const req = importMetaUrl ? (0,
|
|
60242
|
+
const importMetaUrl = import_meta5.url;
|
|
60243
|
+
const req = importMetaUrl ? (0, import_node_module6.createRequire)(importMetaUrl) : require;
|
|
59954
60244
|
const sdk = req("@anthropic-ai/sdk");
|
|
59955
60245
|
const Anthropic = sdk.Anthropic ?? sdk.default;
|
|
59956
60246
|
if (!Anthropic) throw new Error("Could not resolve Anthropic from '@anthropic-ai/sdk'");
|
|
@@ -59976,8 +60266,8 @@ function defaultSender(auth) {
|
|
|
59976
60266
|
}
|
|
59977
60267
|
function defaultPdfSender(auth) {
|
|
59978
60268
|
return async (input) => {
|
|
59979
|
-
const importMetaUrl =
|
|
59980
|
-
const req = importMetaUrl ? (0,
|
|
60269
|
+
const importMetaUrl = import_meta5.url;
|
|
60270
|
+
const req = importMetaUrl ? (0, import_node_module6.createRequire)(importMetaUrl) : require;
|
|
59981
60271
|
const sdk = req("@anthropic-ai/sdk");
|
|
59982
60272
|
const Anthropic = sdk.Anthropic ?? sdk.default;
|
|
59983
60273
|
if (!Anthropic) throw new Error("Could not resolve Anthropic from '@anthropic-ai/sdk'");
|
|
@@ -60288,13 +60578,13 @@ init_postgres();
|
|
|
60288
60578
|
|
|
60289
60579
|
// src/gui/realtime.ts
|
|
60290
60580
|
var import_node_events = require("events");
|
|
60291
|
-
var
|
|
60292
|
-
var
|
|
60581
|
+
var import_node_module7 = require("module");
|
|
60582
|
+
var import_meta6 = {};
|
|
60293
60583
|
var _pgModule = null;
|
|
60294
60584
|
function loadPg() {
|
|
60295
60585
|
if (_pgModule) return _pgModule;
|
|
60296
|
-
const importMetaUrl =
|
|
60297
|
-
const requireFromHere = importMetaUrl ? (0,
|
|
60586
|
+
const importMetaUrl = import_meta6.url;
|
|
60587
|
+
const requireFromHere = importMetaUrl ? (0, import_node_module7.createRequire)(importMetaUrl) : (
|
|
60298
60588
|
// CJS fallback — Node provides `require` on every CJS module scope.
|
|
60299
60589
|
require
|
|
60300
60590
|
);
|
|
@@ -63653,6 +63943,20 @@ var displayConfigJs = `
|
|
|
63653
63943
|
});
|
|
63654
63944
|
}
|
|
63655
63945
|
|
|
63946
|
+
// SINGLE SOURCE OF TRUTH for the assistant's Claude connection state, derived
|
|
63947
|
+
// from /api/assistant/config's claudeAuthKind (oauth | key | null). EVERY
|
|
63948
|
+
// place that shows "Connected with Claude" / opens the API-key panel / gates
|
|
63949
|
+
// on "the assistant has auth" MUST go through this \u2014 never re-derive from raw
|
|
63950
|
+
// fields, or the signals disagree (a stray "or hasAnthropicKey" once made
|
|
63951
|
+
// onboarding show "Connected with Claude" for an API-key-only setup while the
|
|
63952
|
+
// settings panel showed not-connected).
|
|
63953
|
+
// .oauth -> a Claude SUBSCRIPTION is connected ("Connected with Claude")
|
|
63954
|
+
// .any -> some working auth exists (subscription OR API key)
|
|
63955
|
+
function claudeAuth(cfg) {
|
|
63956
|
+
var kind = (cfg && cfg.claudeAuthKind) || null; // 'oauth' | 'key' | null
|
|
63957
|
+
return { kind: kind, oauth: kind === 'oauth', any: kind != null };
|
|
63958
|
+
}
|
|
63959
|
+
|
|
63656
63960
|
// Disable a button + show an inline spinner for the duration of an
|
|
63657
63961
|
// async action so a slow server round-trip can't be double-clicked.
|
|
63658
63962
|
// The fn arg should return a Promise; the button is restored on settle.
|
|
@@ -64443,7 +64747,12 @@ var offlineEditQueueJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
64443
64747
|
if (eventStreamClosed) return;
|
|
64444
64748
|
// Unexpected drop: show the disconnect on the pill and auto-reconnect with
|
|
64445
64749
|
// backoff (the server replays state + render snapshot on reconnect).
|
|
64446
|
-
|
|
64750
|
+
// Preserve the KNOWN mode (cloudMode is the single source of truth, set
|
|
64751
|
+
// from the server's realtime-state message) \u2014 never hardcode 'cloud',
|
|
64752
|
+
// which on a LOCAL (SQLite) workspace would flip cloudMode=true and divert
|
|
64753
|
+
// writes into the offline queue with a bogus "will sync when cloud
|
|
64754
|
+
// reconnects" toast against a workspace that has no cloud.
|
|
64755
|
+
setStatusPill(cloudMode ? 'cloud' : 'local', 'disconnected');
|
|
64447
64756
|
scheduleEventStreamReconnect();
|
|
64448
64757
|
};
|
|
64449
64758
|
}
|
|
@@ -68351,7 +68660,7 @@ var rowContextJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u250
|
|
|
68351
68660
|
var cfg = res[1];
|
|
68352
68661
|
st.name = (id && id.display_name) || '';
|
|
68353
68662
|
st.email = (id && id.email) || '';
|
|
68354
|
-
st.connected =
|
|
68663
|
+
st.connected = claudeAuth(cfg).oauth;
|
|
68355
68664
|
if (!st.wsName && st.name) st.wsName = st.name + "'s Workspace";
|
|
68356
68665
|
render();
|
|
68357
68666
|
});
|
|
@@ -69012,7 +69321,7 @@ var dataModelJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
|
69012
69321
|
'</p>' +
|
|
69013
69322
|
// Connect-with-Claude is the primary path (use your subscription, no
|
|
69014
69323
|
// API key). A pasted API key is demoted to an "Advanced" disclosure.
|
|
69015
|
-
(cfg.
|
|
69324
|
+
(claudeAuth(cfg).oauth
|
|
69016
69325
|
? '<div style="display:flex;align-items:center;gap:10px;margin-bottom:10px">' +
|
|
69017
69326
|
'<span class="feed-source" style="background:var(--accent-soft);color:var(--accent)">Connected with Claude</span>' +
|
|
69018
69327
|
'<button id="asst-oauth-disconnect" class="btn">Disconnect</button>' +
|
|
@@ -69034,7 +69343,7 @@ var dataModelJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
|
69034
69343
|
'</div>' +
|
|
69035
69344
|
'<div id="connect-claude-msg" style="margin-top:6px;font-size:12px;color:var(--text-muted)"></div>' +
|
|
69036
69345
|
'</div>') +
|
|
69037
|
-
'<details style="margin-bottom:12px"' + (cfg.
|
|
69346
|
+
'<details style="margin-bottom:12px"' + (claudeAuth(cfg).kind === 'key' ? ' open' : '') + '>' +
|
|
69038
69347
|
'<summary style="cursor:pointer;font-size:12px;color:var(--text-muted)">Advanced \u2014 use an API key instead</summary>' +
|
|
69039
69348
|
'<div style="margin-top:8px">' +
|
|
69040
69349
|
rowHtml('asst-anthropic', 'Claude API token (chat)', !!cfg.hasAnthropicKey, 'sk-ant-\u2026') +
|
|
@@ -71026,7 +71335,7 @@ var createDatabaseWizardJs = ` // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\
|
|
|
71026
71335
|
function renderComposer() {
|
|
71027
71336
|
var host = document.getElementById('rail-composer'); if (!host) return;
|
|
71028
71337
|
fetchJson('/api/assistant/config').then(function (cfg) {
|
|
71029
|
-
if (cfg
|
|
71338
|
+
if (claudeAuth(cfg).any) {
|
|
71030
71339
|
var micHtml = cfg.hasVoiceKey
|
|
71031
71340
|
? '<button class="composer-mic" id="chat-mic" title="Record voice">\u{1F399}</button>'
|
|
71032
71341
|
: '';
|
|
@@ -77370,6 +77679,7 @@ async function startGuiServer(options) {
|
|
|
77370
77679
|
}
|
|
77371
77680
|
const autoRender = options.autoRender ?? false;
|
|
77372
77681
|
const guiVersion = options.version ?? "";
|
|
77682
|
+
const desktopOpenExternal = options.desktopOpenExternal;
|
|
77373
77683
|
const sessionId = crypto.randomUUID();
|
|
77374
77684
|
let updateService = null;
|
|
77375
77685
|
let activeRef = bootConfigPath && bootOutputDir ? await openConfig(bootConfigPath, bootOutputDir, autoRender, options.realtimeWatchdogMs) : null;
|
|
@@ -77552,6 +77862,20 @@ async function startGuiServer(options) {
|
|
|
77552
77862
|
sendJson(res, { version: guiVersion });
|
|
77553
77863
|
return;
|
|
77554
77864
|
}
|
|
77865
|
+
if (method === "GET" && pathname === "/api/desktop/open") {
|
|
77866
|
+
if (!desktopOpenExternal) {
|
|
77867
|
+
sendJson(res, { error: "not found" }, 404);
|
|
77868
|
+
return;
|
|
77869
|
+
}
|
|
77870
|
+
const target = new URL(req.url ?? "", "http://localhost").searchParams.get("url");
|
|
77871
|
+
if (!target || !/^https?:\/\//i.test(target)) {
|
|
77872
|
+
sendJson(res, { error: "url must be http(s)" }, 400);
|
|
77873
|
+
return;
|
|
77874
|
+
}
|
|
77875
|
+
desktopOpenExternal(target);
|
|
77876
|
+
sendJson(res, { ok: true });
|
|
77877
|
+
return;
|
|
77878
|
+
}
|
|
77555
77879
|
if (method === "GET" && pathname === "/api/update/status") {
|
|
77556
77880
|
sendJson(
|
|
77557
77881
|
res,
|
|
@@ -78120,6 +78444,7 @@ var FileSourceKeyStore = class {
|
|
|
78120
78444
|
DEFAULT_ENTRY_TYPES,
|
|
78121
78445
|
DEFAULT_MAX_NODES,
|
|
78122
78446
|
DEFAULT_TYPE_ALIASES,
|
|
78447
|
+
DenoSqliteAdapter,
|
|
78123
78448
|
EMBEDDINGS_TABLE,
|
|
78124
78449
|
EmbeddingDimensionMismatchError,
|
|
78125
78450
|
EmbeddingScanTooLargeError,
|