load-path.e2e.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  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, { SESSION_FORMAT_VERSION, SessionId } from '@deepseek-ai/dsh-session'
  11. import SessionProjectionRegistry from '@deepseek-ai/dsh-session-projection'
  12. import SqliteSessionPersistence from '@deepseek-ai/dsh-session-persistence-sqlite'
  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 persistencePath = await temporaryPath('canonical.db')
  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(SqliteSessionPersistence, { path: persistencePath })
  36. const loader = Object.create(Loader.prototype) as Loader
  37. const unwrapped = loader.unwrapExports(queryModule) as Parameters<Context['plugin']>[0]
  38. expect(unwrapped).toBe(SqliteSessionQueryEngine)
  39. const query = await ctx.plugin(unwrapped, { path: searchPath })
  40. const id = SessionId('loader-path')
  41. await ctx.sessionPersistence.create({ version: SESSION_FORMAT_VERSION, id, createdAt: 10 })
  42. await ctx.sessionPersistence.append(id, [{
  43. type: 'user/message',
  44. seq: 0,
  45. time: 10,
  46. data: createUserMessage({
  47. content: [{ type: 'text', text: 'real Loader needle' }], source: { kind: 'user' },
  48. }),
  49. surfaceOp: 'append',
  50. }])
  51. await expect(ctx.sessionQuery.searchSessions({ query: 'Loader needle' }))
  52. .resolves.toMatchObject({ items: [{ header: { id }, persisted: true, live: false }] })
  53. await expect(ctx.sessionQuery.listSessions())
  54. .resolves.toMatchObject([{ header: { id }, persisted: true, live: false }])
  55. await query.dispose()
  56. await persistence.dispose()
  57. })
  58. })