fix(sqlite): preserve session metadata contracts

This commit is contained in:
Hypatia May
2026-07-23 22:08:58 +08:00
parent 00191e75dd
commit 0e7fee95c0
6 changed files with 70 additions and 17 deletions

View File

@@ -5,7 +5,7 @@ import { mkdir, open } from 'node:fs/promises'
import { dirname, resolve } from 'node:path'
/** Current derived-index schema version. Incompatible versions reset in place. */
export const SESSION_QUERY_SQLITE_SCHEMA_VERSION = 3
export const SESSION_QUERY_SQLITE_SCHEMA_VERSION = 4
/** SQLite application id protecting unrelated databases from derived resets. */
export const SESSION_QUERY_SQLITE_APPLICATION_ID = 0x44534851
@@ -112,7 +112,7 @@ function ensurePersistentSchema(db: DatabaseSync): void {
CREATE TABLE IF NOT EXISTS persisted_sessions (
id TEXT PRIMARY KEY,
version INTEGER NOT NULL,
created_at INTEGER NOT NULL,
created_at REAL NOT NULL,
cwd TEXT,
parent_session TEXT,
seed_length INTEGER,
@@ -141,7 +141,7 @@ function ensureTemporarySchema(db: DatabaseSync): void {
CREATE TEMP TABLE IF NOT EXISTS live_sessions (
id TEXT PRIMARY KEY,
version INTEGER NOT NULL,
created_at INTEGER NOT NULL,
created_at REAL NOT NULL,
cwd TEXT,
parent_session TEXT,
seed_length INTEGER,

View File

@@ -167,6 +167,22 @@ async function liveContext(config: ConstructorParameters<typeof SessionQuerySqli
}
describe('SQLite session search', () => {
it('indexes finite fractional creation timestamps from live and persisted sources', async () => {
const persisted = header('fractional-persisted', 1.5)
TestPersistence.reset([{ meta: persisted, events: messageEvents('persisted fractional') }])
const ctx = await liveContext()
await ctx.plugin(TestPersistence)
const live = ctx.sessions.create(SessionId('fractional-live'), {
seed: messageEvents('live fractional'),
meta: { createdAt: 2.5 },
})
await expect(ctx.sessionQuery.searchSessions({ query: 'persisted' }))
.resolves.toMatchObject({ items: [{ header: { id: persisted.id, createdAt: 1.5 } }] })
await expect(ctx.sessionQuery.searchSessions({ query: 'live' }))
.resolves.toMatchObject({ items: [{ header: { id: live.id, createdAt: 2.5 } }] })
})
it('searches two-character Unicode61 tokens in live-only sessions', async () => {
const ctx = await liveContext({ path: ':memory:', snippetChars: 20 })
const session = ctx.sessions.create(SessionId('live'), {