load-path.e2e.ts 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import { createUserMessage } from '@deepseek-ai/dsh-llm'
  2. /**
  3. * Keyless real-Loader-path smoke for the combined SQLite session-query service.
  4. *
  5. * @module @deepseek-ai/dsh-session-query-sqlite/tests/load-path
  6. */
  7. import { afterEach, describe, expect, it } from 'vitest'
  8. import { Context } from '@deepseek-ai/cordis'
  9. import Loader from '@deepseek-ai/cordis-plugin-loader'
  10. import SessionStore, { SessionSeq, SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session'
  11. import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
  12. import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl'
  13. import SqliteSessionQueryEngine, * as queryModule from '@deepseek-ai/dsh-session-query-sqlite'
  14. import { mkdtemp, rm } from 'node:fs/promises'
  15. import { tmpdir } from 'node:os'
  16. import { join } from 'node:path'
  17. const temporaryDirectories: string[] = []
  18. afterEach(async () => {
  19. for (const directory of temporaryDirectories.splice(0)) {
  20. await rm(directory, { recursive: true, force: true })
  21. }
  22. })
  23. async function temporaryPath(name: string): Promise<string> {
  24. const directory = await mkdtemp(join(tmpdir(), 'dsh-session-search-loader-'))
  25. temporaryDirectories.push(directory)
  26. return join(directory, name)
  27. }
  28. describe('dsh-session-query-sqlite real Loader path', () => {
  29. it('unwraps, mounts, and searches the real persistence backend', async () => {
  30. const persistenceRoot = await temporaryPath('canonical')
  31. const searchPath = await temporaryPath('derived.db')
  32. const ctx = new Context()
  33. await ctx.plugin(SessionProjectionRegistry)
  34. await ctx.plugin(SessionStore)
  35. const persistence = await ctx.plugin(JsonlSessionPersistence, {
  36. root: persistenceRoot,
  37. compression: 'none',
  38. })
  39. const loader = Object.create(Loader.prototype) as Loader
  40. const unwrapped = loader.unwrapExports(queryModule) as Parameters<Context['plugin']>[0]
  41. expect(unwrapped).toBe(SqliteSessionQueryEngine)
  42. const query = await ctx.plugin(unwrapped, { path: searchPath })
  43. const id = SessionId('loader-path')
  44. const writer = await ctx.sessionPersistence.create({ version: SESSION_FORMAT_VERSION, id, createdAt: 10, isSeeded: false })
  45. await writer.append([{
  46. type: 'user/message',
  47. seq: SessionSeq(0),
  48. time: 10,
  49. data: createUserMessage({
  50. content: [{ type: 'text', text: 'real Loader needle' }], source: { kind: 'user' },
  51. }),
  52. surfaceOp: 'append',
  53. }])
  54. await writer.close()
  55. await expect(ctx.sessionQuery.searchSessions({ query: 'Loader needle' }))
  56. .resolves.toMatchObject({ items: [{ header: { id }, persisted: true, live: false }] })
  57. await expect(ctx.sessionQuery.listSessions())
  58. .resolves.toMatchObject([{ header: { id }, persisted: true, live: false }])
  59. await query.dispose()
  60. await persistence.dispose()
  61. })
  62. })