load-path.e2e.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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, SessionSeq } 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. await ctx.sessionPersistence.create({
  45. version: SESSION_FORMAT_VERSION,
  46. id,
  47. createdAt: 10,
  48. isSeeded: false,
  49. })
  50. await ctx.sessionPersistence.append(id, [{
  51. type: 'user/message',
  52. seq: SessionSeq(0),
  53. time: 10,
  54. data: createUserMessage({
  55. content: [{ type: 'text', text: 'real Loader needle' }], source: { kind: 'user' },
  56. }),
  57. surfaceOp: 'append',
  58. }])
  59. await expect(ctx.sessionQuery.searchSessions({ query: 'Loader needle' }))
  60. .resolves.toMatchObject({ items: [{ header: { id }, persisted: true, live: false }] })
  61. await expect(ctx.sessionQuery.listSessions())
  62. .resolves.toMatchObject([{ header: { id }, persisted: true, live: false }])
  63. await query.dispose()
  64. await persistence.dispose()
  65. })
  66. })