generation.client.spec.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { Context } from '@deepseek-ai/cordis'
  2. import { afterEach, describe, expect, it, vi } from 'vitest'
  3. import {
  4. apply,
  5. type ConnectionGenerationSource,
  6. type ConnectionHandle,
  7. } from '../src/client/index.ts'
  8. type BrowserGlobal = {
  9. location?: { hostname: string; search: string }
  10. }
  11. const contexts = new Set<Context>()
  12. afterEach(async () => {
  13. vi.restoreAllMocks()
  14. delete (globalThis as BrowserGlobal).location
  15. await Promise.all([...contexts].map(async ctx => ctx.fiber.dispose()))
  16. contexts.clear()
  17. })
  18. async function mount(): Promise<ConnectionHandle> {
  19. ;(globalThis as BrowserGlobal).location = { hostname: 'localhost', search: '?fixture' }
  20. const ctx = new Context()
  21. contexts.add(ctx)
  22. await ctx.plugin({ apply, inject: [] })
  23. const connection = ctx.get('connection') as ConnectionHandle | undefined
  24. if (connection === undefined) throw new Error('fixture did not provide Connection')
  25. return connection
  26. }
  27. describe('Connection generation facts', () => {
  28. it('publishes ready-frame Host facts and retracts them when the loop stops', async () => {
  29. const connection = await mount()
  30. const source: ConnectionGenerationSource = (signal, ready) => {
  31. ready({ home: '/home/from-ready' })
  32. return new Promise<void>((resolve) => {
  33. if (signal.aborted) resolve()
  34. else signal.addEventListener('abort', () => { resolve() }, { once: true })
  35. })
  36. }
  37. connection.registerGenerationSource(source)
  38. const seen: Array<string | undefined> = []
  39. const stopListening = connection.generation.subscribe(() => {
  40. seen.push(connection.generation.getSnapshot()?.host.home)
  41. })
  42. const loop = connection.start({}, {
  43. backoffBaseMs: 1,
  44. backoffFactor: 2,
  45. backoffMaxMs: 8,
  46. generationReadyTimeoutMs: 100,
  47. })
  48. await vi.waitFor(() => {
  49. expect(connection.generation.getSnapshot()).toEqual({
  50. id: 1,
  51. host: { home: '/home/from-ready' },
  52. })
  53. })
  54. loop.stop()
  55. expect(connection.generation.getSnapshot()).toBeUndefined()
  56. expect(seen).toEqual(['/home/from-ready', undefined])
  57. stopListening()
  58. })
  59. })