latticesql 0.18.0 → 0.18.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 CHANGED
@@ -536,6 +536,10 @@ var SchemaManager = class {
536
536
  */
537
537
  queryTable(adapter, name) {
538
538
  if (this._tables.has(name)) {
539
+ const def = this._tables.get(name);
540
+ if (def.columns && "deleted_at" in def.columns) {
541
+ return adapter.all(`SELECT * FROM "${name}" WHERE deleted_at IS NULL`);
542
+ }
539
543
  return adapter.all(`SELECT * FROM "${name}"`);
540
544
  }
541
545
  if (this._entityContexts.has(name)) {
package/dist/index.cjs CHANGED
@@ -43,6 +43,7 @@ __export(index_exports, {
43
43
  deriveKey: () => deriveKey,
44
44
  encrypt: () => encrypt,
45
45
  entityFileNames: () => entityFileNames,
46
+ fixSchemaConflicts: () => fixSchemaConflicts,
46
47
  frontmatter: () => frontmatter,
47
48
  generateEntryId: () => generateEntryId,
48
49
  generateWriteEntryId: () => generateWriteEntryId,
@@ -288,6 +289,10 @@ var SchemaManager = class {
288
289
  */
289
290
  queryTable(adapter, name) {
290
291
  if (this._tables.has(name)) {
292
+ const def = this._tables.get(name);
293
+ if (def.columns && "deleted_at" in def.columns) {
294
+ return adapter.all(`SELECT * FROM "${name}" WHERE deleted_at IS NULL`);
295
+ }
291
296
  return adapter.all(`SELECT * FROM "${name}"`);
292
297
  }
293
298
  if (this._entityContexts.has(name)) {
@@ -2644,6 +2649,39 @@ var Lattice = class {
2644
2649
  }
2645
2650
  };
2646
2651
 
2652
+ // src/lifecycle/pre-init.ts
2653
+ function fixSchemaConflicts(db, checks) {
2654
+ for (const { table, requiredColumns } of checks) {
2655
+ if (!tableExists(db, table)) continue;
2656
+ const cols = getColumns(db, table);
2657
+ const missing = requiredColumns.filter((c) => !cols.includes(c));
2658
+ if (missing.length > 0) {
2659
+ renameTable(db, table);
2660
+ }
2661
+ }
2662
+ if (tableExists(db, "__lattice_migrations")) {
2663
+ const versionCol = db.prepare('PRAGMA table_info("__lattice_migrations")').all().find((c) => c.name === "version");
2664
+ if (versionCol && versionCol.type.toUpperCase().includes("INTEGER")) {
2665
+ db.exec(
2666
+ 'ALTER TABLE "__lattice_migrations" RENAME TO "__lattice_migrations_v1"'
2667
+ );
2668
+ }
2669
+ }
2670
+ }
2671
+ function tableExists(db, name) {
2672
+ return !!db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(name);
2673
+ }
2674
+ function getColumns(db, table) {
2675
+ return db.prepare(`PRAGMA table_info("${table}")`).all().map((c) => c.name);
2676
+ }
2677
+ function renameTable(db, table) {
2678
+ const target = `_legacy_${table}`;
2679
+ if (tableExists(db, target)) {
2680
+ db.exec(`DROP TABLE "${target}"`);
2681
+ }
2682
+ db.exec(`ALTER TABLE "${table}" RENAME TO "${target}"`);
2683
+ }
2684
+
2647
2685
  // src/session/parser.ts
2648
2686
  var import_node_crypto4 = require("crypto");
2649
2687
  function generateWriteEntryId(timestamp, agentName, op, table, target) {
@@ -2990,8 +3028,8 @@ function applyWriteEntry(db, entry) {
2990
3028
  if (!TABLE_NAME_RE2.test(table)) {
2991
3029
  return { ok: false, reason: `Invalid table name: "${table}". Only [a-zA-Z0-9_] allowed` };
2992
3030
  }
2993
- const tableExists = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(table);
2994
- if (!tableExists) {
3031
+ const tableExists2 = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(table);
3032
+ if (!tableExists2) {
2995
3033
  return { ok: false, reason: `Unknown table: "${table}"` };
2996
3034
  }
2997
3035
  const columnRows = db.prepare(`PRAGMA table_info("${table}")`).all();
@@ -3061,6 +3099,7 @@ function applyWriteEntry(db, entry) {
3061
3099
  deriveKey,
3062
3100
  encrypt,
3063
3101
  entityFileNames,
3102
+ fixSchemaConflicts,
3064
3103
  frontmatter,
3065
3104
  generateEntryId,
3066
3105
  generateWriteEntryId,
package/dist/index.d.cts CHANGED
@@ -1494,6 +1494,38 @@ declare function parseConfigString(yamlContent: string, configDir: string): Pars
1494
1494
 
1495
1495
  declare function contentHash(content: string): string;
1496
1496
 
1497
+ /**
1498
+ * Fix legacy schema conflicts before Lattice init().
1499
+ *
1500
+ * When upgrading from an older schema version, existing tables may have
1501
+ * incompatible column definitions (e.g., a column with PRIMARY KEY that
1502
+ * new code tries to add via ALTER TABLE, which SQLite doesn't support).
1503
+ *
1504
+ * This utility renames conflicting tables to `_legacy_{name}` so init()
1505
+ * can create fresh tables with the new schema.
1506
+ *
1507
+ * @param db - An open better-sqlite3 database instance
1508
+ * @param checks - Array of { table, requiredColumns } to verify
1509
+ *
1510
+ * @example
1511
+ * ```ts
1512
+ * import Database from 'better-sqlite3';
1513
+ * import { fixSchemaConflicts } from 'latticesql';
1514
+ *
1515
+ * const db = new Database('./app.db');
1516
+ * fixSchemaConflicts(db, [
1517
+ * { table: 'sessions', requiredColumns: ['id'] },
1518
+ * { table: 'messages', requiredColumns: ['id'] },
1519
+ * ]);
1520
+ * db.close();
1521
+ * // Now safe to call lattice.init()
1522
+ * ```
1523
+ */
1524
+ declare function fixSchemaConflicts(db: Database.Database, checks: Array<{
1525
+ table: string;
1526
+ requiredColumns: string[];
1527
+ }>): void;
1528
+
1497
1529
  /**
1498
1530
  * Derive a 256-bit AES key from a master password using scrypt.
1499
1531
  * The salt is fixed per Lattice instance — callers should use a unique
@@ -1760,4 +1792,4 @@ declare function createReadOnlyHeader(options?: ReadOnlyHeaderOptions): string;
1760
1792
  */
1761
1793
  declare const READ_ONLY_HEADER: string;
1762
1794
 
1763
- export { type ApplyWriteResult, type AuditEvent, type BelongsToRelation, type BelongsToSource, type BuiltinTemplateName, type CleanupOptions, type CleanupResult, type CountOptions, type CustomSource, DEFAULT_ENTRY_TYPES, DEFAULT_TYPE_ALIASES, type EnrichedSource, type EnrichmentLookup, type EntityContextDefinition, type EntityContextManifestEntry, type EntityFileManifestInfo, type EntityFileSource, type EntityFileSpec, type EntityProfileField, type EntityProfileSection, type EntityProfileTemplate, type EntityRenderSpec, type EntityRenderTemplate, type EntitySectionPerRow, type EntitySectionsTemplate, type EntityTableColumn, type EntityTableTemplate, type Filter, type FilterOp, type HasManyRelation, type HasManySource, InMemoryStateStore, type InitOptions, Lattice, type LatticeConfig, type LatticeConfigInput, type LatticeEntityDef, type LatticeEntityRenderSpec, type LatticeFieldDef, type LatticeFieldType, type LatticeManifest, type LatticeOptions, type LinkOptions, type ManyToManySource, type MarkdownTableColumn, type Migration, type MultiTableDefinition, type OrderBySpec, type ParseError, type ParseResult, type ParsedConfig, type PkLookup, type PrimaryKey, type QueryOptions, READ_ONLY_HEADER, type ReadOnlyHeaderOptions, type ReconcileOptions, type ReconcileResult, type Relation, type RenderHooks, type RenderResult, type RenderSpec, type ReportConfig, type ReportResult, type ReportSection, type ReportSectionResult, type ReverseSyncError, type ReverseSyncResult, type ReverseSyncUpdate, type Row, type SecurityOptions, type SeedConfig, type SeedLinkSpec, type SeedResult, type SelfSource, type SessionEntry, type SessionParseOptions, type SessionWriteEntry, type SessionWriteOp, type SessionWriteParseResult, type SourceQueryOptions, type StopFn, type SyncResult, type TableDefinition, type TemplateRenderSpec, type UpsertByNaturalKeyOptions, type WatchOptions, type WriteHook, type WriteHookContext, type WritebackDefinition, type WritebackStateStore, applyWriteEntry, contentHash, createReadOnlyHeader, createSQLiteStateStore, decrypt, deriveKey, encrypt, entityFileNames, frontmatter, generateEntryId, generateWriteEntryId, isEncrypted, isV1EntityFiles, manifestPath, markdownTable, normalizeEntityFiles, parseConfigFile, parseConfigString, parseMarkdownEntries, parseSessionMD, parseSessionWrites, readManifest, slugify, truncate, validateEntryId, writeManifest };
1795
+ export { type ApplyWriteResult, type AuditEvent, type BelongsToRelation, type BelongsToSource, type BuiltinTemplateName, type CleanupOptions, type CleanupResult, type CountOptions, type CustomSource, DEFAULT_ENTRY_TYPES, DEFAULT_TYPE_ALIASES, type EnrichedSource, type EnrichmentLookup, type EntityContextDefinition, type EntityContextManifestEntry, type EntityFileManifestInfo, type EntityFileSource, type EntityFileSpec, type EntityProfileField, type EntityProfileSection, type EntityProfileTemplate, type EntityRenderSpec, type EntityRenderTemplate, type EntitySectionPerRow, type EntitySectionsTemplate, type EntityTableColumn, type EntityTableTemplate, type Filter, type FilterOp, type HasManyRelation, type HasManySource, InMemoryStateStore, type InitOptions, Lattice, type LatticeConfig, type LatticeConfigInput, type LatticeEntityDef, type LatticeEntityRenderSpec, type LatticeFieldDef, type LatticeFieldType, type LatticeManifest, type LatticeOptions, type LinkOptions, type ManyToManySource, type MarkdownTableColumn, type Migration, type MultiTableDefinition, type OrderBySpec, type ParseError, type ParseResult, type ParsedConfig, type PkLookup, type PrimaryKey, type QueryOptions, READ_ONLY_HEADER, type ReadOnlyHeaderOptions, type ReconcileOptions, type ReconcileResult, type Relation, type RenderHooks, type RenderResult, type RenderSpec, type ReportConfig, type ReportResult, type ReportSection, type ReportSectionResult, type ReverseSyncError, type ReverseSyncResult, type ReverseSyncUpdate, type Row, type SecurityOptions, type SeedConfig, type SeedLinkSpec, type SeedResult, type SelfSource, type SessionEntry, type SessionParseOptions, type SessionWriteEntry, type SessionWriteOp, type SessionWriteParseResult, type SourceQueryOptions, type StopFn, type SyncResult, type TableDefinition, type TemplateRenderSpec, type UpsertByNaturalKeyOptions, type WatchOptions, type WriteHook, type WriteHookContext, type WritebackDefinition, type WritebackStateStore, applyWriteEntry, contentHash, createReadOnlyHeader, createSQLiteStateStore, decrypt, deriveKey, encrypt, entityFileNames, fixSchemaConflicts, frontmatter, generateEntryId, generateWriteEntryId, isEncrypted, isV1EntityFiles, manifestPath, markdownTable, normalizeEntityFiles, parseConfigFile, parseConfigString, parseMarkdownEntries, parseSessionMD, parseSessionWrites, readManifest, slugify, truncate, validateEntryId, writeManifest };
package/dist/index.d.ts CHANGED
@@ -1494,6 +1494,38 @@ declare function parseConfigString(yamlContent: string, configDir: string): Pars
1494
1494
 
1495
1495
  declare function contentHash(content: string): string;
1496
1496
 
1497
+ /**
1498
+ * Fix legacy schema conflicts before Lattice init().
1499
+ *
1500
+ * When upgrading from an older schema version, existing tables may have
1501
+ * incompatible column definitions (e.g., a column with PRIMARY KEY that
1502
+ * new code tries to add via ALTER TABLE, which SQLite doesn't support).
1503
+ *
1504
+ * This utility renames conflicting tables to `_legacy_{name}` so init()
1505
+ * can create fresh tables with the new schema.
1506
+ *
1507
+ * @param db - An open better-sqlite3 database instance
1508
+ * @param checks - Array of { table, requiredColumns } to verify
1509
+ *
1510
+ * @example
1511
+ * ```ts
1512
+ * import Database from 'better-sqlite3';
1513
+ * import { fixSchemaConflicts } from 'latticesql';
1514
+ *
1515
+ * const db = new Database('./app.db');
1516
+ * fixSchemaConflicts(db, [
1517
+ * { table: 'sessions', requiredColumns: ['id'] },
1518
+ * { table: 'messages', requiredColumns: ['id'] },
1519
+ * ]);
1520
+ * db.close();
1521
+ * // Now safe to call lattice.init()
1522
+ * ```
1523
+ */
1524
+ declare function fixSchemaConflicts(db: Database.Database, checks: Array<{
1525
+ table: string;
1526
+ requiredColumns: string[];
1527
+ }>): void;
1528
+
1497
1529
  /**
1498
1530
  * Derive a 256-bit AES key from a master password using scrypt.
1499
1531
  * The salt is fixed per Lattice instance — callers should use a unique
@@ -1760,4 +1792,4 @@ declare function createReadOnlyHeader(options?: ReadOnlyHeaderOptions): string;
1760
1792
  */
1761
1793
  declare const READ_ONLY_HEADER: string;
1762
1794
 
1763
- export { type ApplyWriteResult, type AuditEvent, type BelongsToRelation, type BelongsToSource, type BuiltinTemplateName, type CleanupOptions, type CleanupResult, type CountOptions, type CustomSource, DEFAULT_ENTRY_TYPES, DEFAULT_TYPE_ALIASES, type EnrichedSource, type EnrichmentLookup, type EntityContextDefinition, type EntityContextManifestEntry, type EntityFileManifestInfo, type EntityFileSource, type EntityFileSpec, type EntityProfileField, type EntityProfileSection, type EntityProfileTemplate, type EntityRenderSpec, type EntityRenderTemplate, type EntitySectionPerRow, type EntitySectionsTemplate, type EntityTableColumn, type EntityTableTemplate, type Filter, type FilterOp, type HasManyRelation, type HasManySource, InMemoryStateStore, type InitOptions, Lattice, type LatticeConfig, type LatticeConfigInput, type LatticeEntityDef, type LatticeEntityRenderSpec, type LatticeFieldDef, type LatticeFieldType, type LatticeManifest, type LatticeOptions, type LinkOptions, type ManyToManySource, type MarkdownTableColumn, type Migration, type MultiTableDefinition, type OrderBySpec, type ParseError, type ParseResult, type ParsedConfig, type PkLookup, type PrimaryKey, type QueryOptions, READ_ONLY_HEADER, type ReadOnlyHeaderOptions, type ReconcileOptions, type ReconcileResult, type Relation, type RenderHooks, type RenderResult, type RenderSpec, type ReportConfig, type ReportResult, type ReportSection, type ReportSectionResult, type ReverseSyncError, type ReverseSyncResult, type ReverseSyncUpdate, type Row, type SecurityOptions, type SeedConfig, type SeedLinkSpec, type SeedResult, type SelfSource, type SessionEntry, type SessionParseOptions, type SessionWriteEntry, type SessionWriteOp, type SessionWriteParseResult, type SourceQueryOptions, type StopFn, type SyncResult, type TableDefinition, type TemplateRenderSpec, type UpsertByNaturalKeyOptions, type WatchOptions, type WriteHook, type WriteHookContext, type WritebackDefinition, type WritebackStateStore, applyWriteEntry, contentHash, createReadOnlyHeader, createSQLiteStateStore, decrypt, deriveKey, encrypt, entityFileNames, frontmatter, generateEntryId, generateWriteEntryId, isEncrypted, isV1EntityFiles, manifestPath, markdownTable, normalizeEntityFiles, parseConfigFile, parseConfigString, parseMarkdownEntries, parseSessionMD, parseSessionWrites, readManifest, slugify, truncate, validateEntryId, writeManifest };
1795
+ export { type ApplyWriteResult, type AuditEvent, type BelongsToRelation, type BelongsToSource, type BuiltinTemplateName, type CleanupOptions, type CleanupResult, type CountOptions, type CustomSource, DEFAULT_ENTRY_TYPES, DEFAULT_TYPE_ALIASES, type EnrichedSource, type EnrichmentLookup, type EntityContextDefinition, type EntityContextManifestEntry, type EntityFileManifestInfo, type EntityFileSource, type EntityFileSpec, type EntityProfileField, type EntityProfileSection, type EntityProfileTemplate, type EntityRenderSpec, type EntityRenderTemplate, type EntitySectionPerRow, type EntitySectionsTemplate, type EntityTableColumn, type EntityTableTemplate, type Filter, type FilterOp, type HasManyRelation, type HasManySource, InMemoryStateStore, type InitOptions, Lattice, type LatticeConfig, type LatticeConfigInput, type LatticeEntityDef, type LatticeEntityRenderSpec, type LatticeFieldDef, type LatticeFieldType, type LatticeManifest, type LatticeOptions, type LinkOptions, type ManyToManySource, type MarkdownTableColumn, type Migration, type MultiTableDefinition, type OrderBySpec, type ParseError, type ParseResult, type ParsedConfig, type PkLookup, type PrimaryKey, type QueryOptions, READ_ONLY_HEADER, type ReadOnlyHeaderOptions, type ReconcileOptions, type ReconcileResult, type Relation, type RenderHooks, type RenderResult, type RenderSpec, type ReportConfig, type ReportResult, type ReportSection, type ReportSectionResult, type ReverseSyncError, type ReverseSyncResult, type ReverseSyncUpdate, type Row, type SecurityOptions, type SeedConfig, type SeedLinkSpec, type SeedResult, type SelfSource, type SessionEntry, type SessionParseOptions, type SessionWriteEntry, type SessionWriteOp, type SessionWriteParseResult, type SourceQueryOptions, type StopFn, type SyncResult, type TableDefinition, type TemplateRenderSpec, type UpsertByNaturalKeyOptions, type WatchOptions, type WriteHook, type WriteHookContext, type WritebackDefinition, type WritebackStateStore, applyWriteEntry, contentHash, createReadOnlyHeader, createSQLiteStateStore, decrypt, deriveKey, encrypt, entityFileNames, fixSchemaConflicts, frontmatter, generateEntryId, generateWriteEntryId, isEncrypted, isV1EntityFiles, manifestPath, markdownTable, normalizeEntityFiles, parseConfigFile, parseConfigString, parseMarkdownEntries, parseSessionMD, parseSessionWrites, readManifest, slugify, truncate, validateEntryId, writeManifest };
package/dist/index.js CHANGED
@@ -222,6 +222,10 @@ var SchemaManager = class {
222
222
  */
223
223
  queryTable(adapter, name) {
224
224
  if (this._tables.has(name)) {
225
+ const def = this._tables.get(name);
226
+ if (def.columns && "deleted_at" in def.columns) {
227
+ return adapter.all(`SELECT * FROM "${name}" WHERE deleted_at IS NULL`);
228
+ }
225
229
  return adapter.all(`SELECT * FROM "${name}"`);
226
230
  }
227
231
  if (this._entityContexts.has(name)) {
@@ -2578,6 +2582,39 @@ var Lattice = class {
2578
2582
  }
2579
2583
  };
2580
2584
 
2585
+ // src/lifecycle/pre-init.ts
2586
+ function fixSchemaConflicts(db, checks) {
2587
+ for (const { table, requiredColumns } of checks) {
2588
+ if (!tableExists(db, table)) continue;
2589
+ const cols = getColumns(db, table);
2590
+ const missing = requiredColumns.filter((c) => !cols.includes(c));
2591
+ if (missing.length > 0) {
2592
+ renameTable(db, table);
2593
+ }
2594
+ }
2595
+ if (tableExists(db, "__lattice_migrations")) {
2596
+ const versionCol = db.prepare('PRAGMA table_info("__lattice_migrations")').all().find((c) => c.name === "version");
2597
+ if (versionCol && versionCol.type.toUpperCase().includes("INTEGER")) {
2598
+ db.exec(
2599
+ 'ALTER TABLE "__lattice_migrations" RENAME TO "__lattice_migrations_v1"'
2600
+ );
2601
+ }
2602
+ }
2603
+ }
2604
+ function tableExists(db, name) {
2605
+ return !!db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(name);
2606
+ }
2607
+ function getColumns(db, table) {
2608
+ return db.prepare(`PRAGMA table_info("${table}")`).all().map((c) => c.name);
2609
+ }
2610
+ function renameTable(db, table) {
2611
+ const target = `_legacy_${table}`;
2612
+ if (tableExists(db, target)) {
2613
+ db.exec(`DROP TABLE "${target}"`);
2614
+ }
2615
+ db.exec(`ALTER TABLE "${table}" RENAME TO "${target}"`);
2616
+ }
2617
+
2581
2618
  // src/session/parser.ts
2582
2619
  import { createHash as createHash2 } from "crypto";
2583
2620
  function generateWriteEntryId(timestamp, agentName, op, table, target) {
@@ -2924,8 +2961,8 @@ function applyWriteEntry(db, entry) {
2924
2961
  if (!TABLE_NAME_RE2.test(table)) {
2925
2962
  return { ok: false, reason: `Invalid table name: "${table}". Only [a-zA-Z0-9_] allowed` };
2926
2963
  }
2927
- const tableExists = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(table);
2928
- if (!tableExists) {
2964
+ const tableExists2 = db.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?").get(table);
2965
+ if (!tableExists2) {
2929
2966
  return { ok: false, reason: `Unknown table: "${table}"` };
2930
2967
  }
2931
2968
  const columnRows = db.prepare(`PRAGMA table_info("${table}")`).all();
@@ -2994,6 +3031,7 @@ export {
2994
3031
  deriveKey,
2995
3032
  encrypt,
2996
3033
  entityFileNames,
3034
+ fixSchemaConflicts,
2997
3035
  frontmatter,
2998
3036
  generateEntryId,
2999
3037
  generateWriteEntryId,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "latticesql",
3
- "version": "0.18.0",
3
+ "version": "0.18.2",
4
4
  "description": "Persistent structured memory for AI agent systems — SQLite ↔ LLM context bridge",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",