refactor: apply repository naming contract
Apply the accepted pre-release package, service, type, directory, and role renames as one repository-wide change.
This commit is contained in:
@@ -6,7 +6,7 @@ import { tmpdir } from 'node:os'
|
||||
import { dirname, isAbsolute, join, relative, resolve } from 'node:path'
|
||||
import SessionStore, { SessionId } from '@deepseek-ai/dsh-session'
|
||||
import type { Session, SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session'
|
||||
import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl'
|
||||
import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl'
|
||||
import {
|
||||
encodeSegment, eventLines, logPath, projectDir, projectKey, scanLog, sessionDir, SessionLogScanner, toHeaderLine,
|
||||
} from '../src/format.ts'
|
||||
@@ -104,7 +104,7 @@ runPersistenceContract('jsonl-none', async () => {
|
||||
const dir = await mkdtemp(join(tmpdir(), 'dsh-jsonl-'))
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SessionStore)
|
||||
const fiber = await ctx.plugin(SessionPersistenceJsonl, { root: dir, compression: 'none' })
|
||||
const fiber = await ctx.plugin(JsonlSessionPersistence, { root: dir, compression: 'none' })
|
||||
return {
|
||||
persistence: ctx.sessionPersistence,
|
||||
dispose: async () => {
|
||||
@@ -120,7 +120,7 @@ runCoordinatorContract('jsonl-none', async (): Promise<CoordinatorFixture> => {
|
||||
const dir = await mkdtemp(join(tmpdir(), 'dsh-jsonl-coord-'))
|
||||
return {
|
||||
mount: async (ctx) => {
|
||||
const fiber = await ctx.plugin(SessionPersistenceJsonl, { root: dir, compression: 'none' })
|
||||
const fiber = await ctx.plugin(JsonlSessionPersistence, { root: dir, compression: 'none' })
|
||||
return fiber
|
||||
},
|
||||
corruptTail: async (id, cwd) => {
|
||||
@@ -133,7 +133,7 @@ runCoordinatorContract('jsonl-none', async (): Promise<CoordinatorFixture> => {
|
||||
}
|
||||
})
|
||||
|
||||
describe('SessionPersistenceJsonl: format helpers', () => {
|
||||
describe('JsonlSessionPersistence: format helpers', () => {
|
||||
it('encodeSegment neutralizes traversal, separators, and absolute paths', () => {
|
||||
expect(encodeSegment('..')).toBe('~002E~002E')
|
||||
expect(encodeSegment('.')).toBe('~002E')
|
||||
@@ -174,7 +174,7 @@ describe('SessionPersistenceJsonl: format helpers', () => {
|
||||
const absoluteRoot = await freshRoot()
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SessionStore)
|
||||
const fiber = await ctx.plugin(SessionPersistenceJsonl, {
|
||||
const fiber = await ctx.plugin(JsonlSessionPersistence, {
|
||||
root: relative(process.cwd(), absoluteRoot),
|
||||
compression: 'none',
|
||||
writeBatchMaxDelayMs: 1,
|
||||
@@ -191,7 +191,7 @@ describe('SessionPersistenceJsonl: format helpers', () => {
|
||||
const absoluteRoot = await freshRoot()
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SessionStore)
|
||||
const fiber = await ctx.plugin(SessionPersistenceJsonl, { root: absoluteRoot, compression: 'none' })
|
||||
const fiber = await ctx.plugin(JsonlSessionPersistence, { root: absoluteRoot, compression: 'none' })
|
||||
// A future format need not satisfy today's header shape at all (no
|
||||
// createdAt, unknown fields): the version must be refused before shape
|
||||
// validation, so the user sees the upgrade direction.
|
||||
@@ -210,7 +210,7 @@ describe('SessionPersistenceJsonl: format helpers', () => {
|
||||
const absoluteRoot = await freshRoot()
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SessionStore)
|
||||
const fiber = await ctx.plugin(SessionPersistenceJsonl, { root: absoluteRoot, compression: 'none' })
|
||||
const fiber = await ctx.plugin(JsonlSessionPersistence, { root: absoluteRoot, compression: 'none' })
|
||||
// Valid JSON that is no object carries no version to compare, so the
|
||||
// version guard must pass it through to the corruption diagnostics.
|
||||
const id = SessionId('scalar-header')
|
||||
@@ -227,7 +227,7 @@ describe('SessionPersistenceJsonl: format helpers', () => {
|
||||
const absoluteRoot = await freshRoot()
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SessionStore)
|
||||
const fiber = await ctx.plugin(SessionPersistenceJsonl, { root: absoluteRoot, compression: 'none' })
|
||||
const fiber = await ctx.plugin(JsonlSessionPersistence, { root: absoluteRoot, compression: 'none' })
|
||||
// A future header's id field is as untrusted as the rest of its shape:
|
||||
// the refusal must still name the session it read, not crash on the type.
|
||||
const id = SessionId('numeric-id')
|
||||
@@ -244,7 +244,7 @@ describe('SessionPersistenceJsonl: format helpers', () => {
|
||||
const absoluteRoot = await freshRoot()
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SessionStore)
|
||||
const fiber = await ctx.plugin(SessionPersistenceJsonl, { root: absoluteRoot, compression: 'none' })
|
||||
const fiber = await ctx.plugin(JsonlSessionPersistence, { root: absoluteRoot, compression: 'none' })
|
||||
const m = { ...meta('newer-format', '/work'), version: 7 }
|
||||
await ctx.sessionPersistence.create(m)
|
||||
await ctx.sessionPersistence.append(m.id, [
|
||||
@@ -258,13 +258,13 @@ describe('SessionPersistenceJsonl: format helpers', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('SessionPersistenceJsonl: durability and crash semantics', () => {
|
||||
describe('JsonlSessionPersistence: durability and crash semantics', () => {
|
||||
let ctx: Context
|
||||
beforeEach(async () => {
|
||||
root = await freshRoot()
|
||||
ctx = new Context()
|
||||
await ctx.plugin(SessionStore)
|
||||
await ctx.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
|
||||
await ctx.plugin(JsonlSessionPersistence, { root, compression: 'none' })
|
||||
})
|
||||
afterEach(async () => { await ctx.fiber.dispose() })
|
||||
|
||||
@@ -382,13 +382,13 @@ describe('SessionPersistenceJsonl: durability and crash semantics', () => {
|
||||
|
||||
const reopenedCtx = new Context()
|
||||
await reopenedCtx.plugin(SessionStore)
|
||||
await reopenedCtx.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
|
||||
await reopenedCtx.plugin(JsonlSessionPersistence, { root, compression: 'none' })
|
||||
expect((await reopenedCtx.sessionPersistence.listSnapshots())[0]?.revision).toBe(revision)
|
||||
|
||||
const otherRoot = await freshRoot()
|
||||
const otherCtx = new Context()
|
||||
await otherCtx.plugin(SessionStore)
|
||||
await otherCtx.plugin(SessionPersistenceJsonl, { root: otherRoot, compression: 'none' })
|
||||
await otherCtx.plugin(JsonlSessionPersistence, { root: otherRoot, compression: 'none' })
|
||||
await otherCtx.sessionPersistence.create(m)
|
||||
await otherCtx.sessionPersistence.append(m.id, oneTurnLog())
|
||||
expect((await otherCtx.sessionPersistence.listSnapshots())[0]?.revision).not.toBe(revision)
|
||||
@@ -401,7 +401,7 @@ describe('SessionPersistenceJsonl: durability and crash semantics', () => {
|
||||
const m = meta('stored-prefix-revision')
|
||||
await ctx.sessionPersistence.create(m)
|
||||
await ctx.sessionPersistence.append(m.id, oneTurnLog())
|
||||
const persistence = ctx.sessionPersistence as SessionPersistenceJsonl
|
||||
const persistence = ctx.sessionPersistence as JsonlSessionPersistence
|
||||
|
||||
const stored = await persistence.loadStored(m.id)
|
||||
expect(stored?.revision).toBe(await persistence.readStoredRevision(m.id))
|
||||
@@ -412,7 +412,7 @@ describe('SessionPersistenceJsonl: durability and crash semantics', () => {
|
||||
const m = meta('stored-prefix-revision-race')
|
||||
await ctx.sessionPersistence.create(m)
|
||||
await ctx.sessionPersistence.append(m.id, oneTurnLog())
|
||||
const persistence = ctx.sessionPersistence as SessionPersistenceJsonl
|
||||
const persistence = ctx.sessionPersistence as JsonlSessionPersistence
|
||||
statRace.path = rawLogPath(root, m.cwd, m.id)
|
||||
|
||||
await expect(persistence.loadStored(m.id)).resolves.toMatchObject({ events: oneTurnLog() })
|
||||
@@ -423,7 +423,7 @@ describe('SessionPersistenceJsonl: durability and crash semantics', () => {
|
||||
const m = meta('stored-revision-race')
|
||||
await ctx.sessionPersistence.create(m)
|
||||
await ctx.sessionPersistence.append(m.id, oneTurnLog())
|
||||
const persistence = ctx.sessionPersistence as SessionPersistenceJsonl
|
||||
const persistence = ctx.sessionPersistence as JsonlSessionPersistence
|
||||
const internals = persistence as unknown as {
|
||||
findLog(id: SessionId, signal?: AbortSignal): Promise<string | undefined>
|
||||
}
|
||||
@@ -780,12 +780,12 @@ describe('SessionPersistenceJsonl: durability and crash semantics', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('SessionPersistenceJsonl: write path (session/event → flush)', () => {
|
||||
describe('JsonlSessionPersistence: write path (session/event → flush)', () => {
|
||||
it('concurrent sessions do not cross buffers', async () => {
|
||||
root = await freshRoot()
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SessionStore)
|
||||
await ctx.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
|
||||
await ctx.plugin(JsonlSessionPersistence, { root, compression: 'none' })
|
||||
|
||||
const a = ctx.sessions.create(SessionId('sa'))
|
||||
const b = ctx.sessions.create(SessionId('sb'))
|
||||
@@ -814,7 +814,7 @@ describe('SessionPersistenceJsonl: write path (session/event → flush)', () =>
|
||||
})
|
||||
|
||||
|
||||
describe('SessionPersistenceJsonl: scanLog unit', () => {
|
||||
describe('JsonlSessionPersistence: scanLog unit', () => {
|
||||
it('requires exactly one newline-terminated header record', () => {
|
||||
const header = JSON.stringify(toHeaderLine(meta('scanner-header')))
|
||||
expect(() => new SessionLogScanner(Buffer.alloc(0))).toThrow(/header-less/)
|
||||
@@ -1012,7 +1012,7 @@ describe('SessionPersistenceJsonl: scanLog unit', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('SessionPersistenceJsonl: default packed chunk rows', () => {
|
||||
describe('JsonlSessionPersistence: default packed chunk rows', () => {
|
||||
let ctx: Context
|
||||
beforeEach(async () => {
|
||||
root = await freshRoot()
|
||||
@@ -1020,7 +1020,7 @@ describe('SessionPersistenceJsonl: default packed chunk rows', () => {
|
||||
await ctx.plugin(SessionStore)
|
||||
// compression: 'none' — these tests assert the textual storage-record layout
|
||||
// (row tags per line); packing is orthogonal to the physical encoding.
|
||||
await ctx.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
|
||||
await ctx.plugin(JsonlSessionPersistence, { root, compression: 'none' })
|
||||
})
|
||||
afterEach(async () => { await ctx.fiber.dispose() })
|
||||
|
||||
@@ -1070,7 +1070,7 @@ describe('SessionPersistenceJsonl: default packed chunk rows', () => {
|
||||
const unpackedRoot = await freshRoot()
|
||||
const unpacked = new Context()
|
||||
await unpacked.plugin(SessionStore)
|
||||
await unpacked.plugin(SessionPersistenceJsonl, {
|
||||
await unpacked.plugin(JsonlSessionPersistence, {
|
||||
root: unpackedRoot,
|
||||
packChunks: false,
|
||||
compression: 'none',
|
||||
@@ -1163,13 +1163,13 @@ describe('SessionPersistenceJsonl: default packed chunk rows', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
describe('JsonlSessionPersistence: edge cases', () => {
|
||||
let ctx: Context
|
||||
beforeEach(async () => {
|
||||
root = await freshRoot()
|
||||
ctx = new Context()
|
||||
await ctx.plugin(SessionStore)
|
||||
await ctx.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
|
||||
await ctx.plugin(JsonlSessionPersistence, { root, compression: 'none' })
|
||||
})
|
||||
afterEach(async () => { await ctx.fiber.dispose() })
|
||||
|
||||
@@ -1383,7 +1383,7 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
// stored cwd check rejects instead of grafting no-cwd events onto that log.
|
||||
const ctx2 = new Context()
|
||||
await ctx2.plugin(SessionStore)
|
||||
await ctx2.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
|
||||
await ctx2.plugin(JsonlSessionPersistence, { root, compression: 'none' })
|
||||
let b!: Session
|
||||
await ctx2.plugin(Object.assign((inner: Context) => {
|
||||
b = inner.sessions.create(SessionId('x')) // no cwd
|
||||
@@ -1441,7 +1441,7 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
it('list returns nothing when the root directory does not exist', async () => {
|
||||
const ctx2 = new Context()
|
||||
await ctx2.plugin(SessionStore)
|
||||
await ctx2.plugin(SessionPersistenceJsonl, {
|
||||
await ctx2.plugin(JsonlSessionPersistence, {
|
||||
root: join(root, 'does-not-exist-yet'),
|
||||
compression: 'none',
|
||||
})
|
||||
@@ -1454,7 +1454,7 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
await writeFile(filePath, 'x')
|
||||
const ctx2 = new Context()
|
||||
await ctx2.plugin(SessionStore)
|
||||
await expect(ctx2.plugin(SessionPersistenceJsonl, { root: filePath, compression: 'none' })).rejects.toThrow(/ENOTDIR/)
|
||||
await expect(ctx2.plugin(JsonlSessionPersistence, { root: filePath, compression: 'none' })).rejects.toThrow(/ENOTDIR/)
|
||||
await ctx2.fiber.dispose()
|
||||
})
|
||||
|
||||
@@ -1477,7 +1477,7 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
const cwd = '/x'
|
||||
const ctx2 = new Context()
|
||||
await ctx2.plugin(SessionStore)
|
||||
await ctx2.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
|
||||
await ctx2.plugin(JsonlSessionPersistence, { root, compression: 'none' })
|
||||
await writeFile(projectDir(root, cwd), 'x') // project path is now a file
|
||||
let s!: Session
|
||||
await ctx2.plugin(Object.assign((inner: Context) => {
|
||||
@@ -1500,7 +1500,7 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
// that the same append then performs before writing.
|
||||
const ctx2 = new Context()
|
||||
await ctx2.plugin(SessionStore)
|
||||
await ctx2.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
|
||||
await ctx2.plugin(JsonlSessionPersistence, { root, compression: 'none' })
|
||||
await ctx2.sessionPersistence.append(m.id, [
|
||||
{ type: 'turn/start', seq: 6, time: 9, data: { turn: 2 } },
|
||||
{ type: 'turn/end', seq: 7, time: 10, data: { turn: 2, reason: { kind: 'completed' } } },
|
||||
@@ -1536,7 +1536,7 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
// nondeterministic. create scans every project, not just meta.cwd's.
|
||||
const ctx2 = new Context()
|
||||
await ctx2.plugin(SessionStore)
|
||||
await ctx2.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
|
||||
await ctx2.plugin(JsonlSessionPersistence, { root, compression: 'none' })
|
||||
await expect(ctx2.sessionPersistence.create(meta('dup-id', '/projB')))
|
||||
.rejects.toThrow(/already has a persisted log on disk/)
|
||||
await ctx2.fiber.dispose()
|
||||
@@ -1546,7 +1546,7 @@ describe('SessionPersistenceJsonl: edge cases', () => {
|
||||
root = await freshRoot()
|
||||
const ctx2 = new Context()
|
||||
await ctx2.plugin(SessionStore)
|
||||
await ctx2.plugin(SessionPersistenceJsonl, { root, compression: 'none' })
|
||||
await ctx2.plugin(JsonlSessionPersistence, { root, compression: 'none' })
|
||||
const session = ctx2.sessions.create(SessionId('flush-fail'))
|
||||
// A full turn lands in the write-behind buffer.
|
||||
session.append('turn/start', { turn: 1 })
|
||||
|
||||
@@ -7,7 +7,7 @@ import { join } from 'node:path'
|
||||
import { performance } from 'node:perf_hooks'
|
||||
import SessionStore, { SessionId } from '@deepseek-ai/dsh-session'
|
||||
import type { SessionEvent } from '@deepseek-ai/dsh-session'
|
||||
import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl'
|
||||
import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl'
|
||||
import { logPath, scanLog, sessionDir, toHeaderLine, type JsonlCompression } from '../src/format.ts'
|
||||
import {
|
||||
compressZstdFrame, createZstdFrameDecoder, decompressZstdFrame, decompressZstdPrefix, scanZstdFrames,
|
||||
@@ -44,7 +44,7 @@ async function mount(root: string, compression?: JsonlCompression): Promise<Cont
|
||||
const ctx = new Context()
|
||||
contexts.push(ctx)
|
||||
await ctx.plugin(SessionStore)
|
||||
await ctx.plugin(SessionPersistenceJsonl, {
|
||||
await ctx.plugin(JsonlSessionPersistence, {
|
||||
root,
|
||||
...(compression === undefined ? {} : { compression }),
|
||||
})
|
||||
@@ -116,7 +116,7 @@ runPersistenceContract('jsonl-zstd', async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'dsh-jsonl-zstd-contract-'))
|
||||
const ctx = new Context()
|
||||
await ctx.plugin(SessionStore)
|
||||
const fiber = await ctx.plugin(SessionPersistenceJsonl, { root })
|
||||
const fiber = await ctx.plugin(JsonlSessionPersistence, { root })
|
||||
return {
|
||||
persistence: ctx.sessionPersistence,
|
||||
dispose: async () => {
|
||||
@@ -129,7 +129,7 @@ runPersistenceContract('jsonl-zstd', async () => {
|
||||
runCoordinatorContract('jsonl-zstd', async (): Promise<CoordinatorFixture> => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'dsh-jsonl-zstd-coordinator-'))
|
||||
return {
|
||||
mount: async ctx => ctx.plugin(SessionPersistenceJsonl, { root }),
|
||||
mount: async ctx => ctx.plugin(JsonlSessionPersistence, { root }),
|
||||
corruptTail: async (id, cwd) => {
|
||||
const line = JSON.stringify({
|
||||
type: 'assistant/chunk',
|
||||
@@ -331,7 +331,7 @@ describe('Zstandard frame structure', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('SessionPersistenceJsonl: default Zstandard encoding', () => {
|
||||
describe('JsonlSessionPersistence: default Zstandard encoding', () => {
|
||||
it('writes .jsonl.zstd by default with one header frame and one first-batch frame', async () => {
|
||||
const root = await freshRoot()
|
||||
const ctx = await mount(root)
|
||||
@@ -394,9 +394,9 @@ describe('SessionPersistenceJsonl: default Zstandard encoding', () => {
|
||||
const ctx = new Context()
|
||||
contexts.push(ctx)
|
||||
await ctx.plugin(SessionStore)
|
||||
let backend!: SessionPersistenceJsonl
|
||||
let backend!: JsonlSessionPersistence
|
||||
await ctx.plugin(Object.assign((inner: Context) => {
|
||||
backend = new SessionPersistenceJsonl(inner, { root })
|
||||
backend = new JsonlSessionPersistence(inner, { root })
|
||||
}, { inject: ['sessions'] }))
|
||||
const header = meta('direct-default')
|
||||
const path = logPath(root, header.cwd, header.id, 'zstd')
|
||||
@@ -695,7 +695,7 @@ describe('SessionPersistenceJsonl: default Zstandard encoding', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('SessionPersistenceJsonl: encoding selection', () => {
|
||||
describe('JsonlSessionPersistence: encoding selection', () => {
|
||||
it('rejects roots owned by the opposite encoding in both directions', async () => {
|
||||
const rawRoot = await freshRoot('dsh-jsonl-raw-mismatch-')
|
||||
const raw = await mount(rawRoot, 'none')
|
||||
@@ -727,7 +727,7 @@ describe('SessionPersistenceJsonl: encoding selection', () => {
|
||||
'',
|
||||
].join('\n'))
|
||||
await expect(ctx.sessionPersistence.load(loadHeader.id)).rejects.toThrow(/uses \.jsonl/)
|
||||
await expect((ctx.sessionPersistence as SessionPersistenceJsonl).loadStored(loadHeader.id))
|
||||
await expect((ctx.sessionPersistence as JsonlSessionPersistence).loadStored(loadHeader.id))
|
||||
.rejects.toThrow(/uses \.jsonl/)
|
||||
await expect(ctx.sessionPersistence.list()).rejects.toThrow(/uses \.jsonl/)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user