refactor(schedule): make absolute times explicit
This commit is contained in:
@@ -12,11 +12,8 @@ import TypertRegistry from '@deepseek-ai/dsh-typert-registry'
|
||||
import * as RuntimeClient from '../src/client/index.ts'
|
||||
import type { SessionsService } from '../src/client/sessions/service.ts'
|
||||
import type { WorkspacesService } from '../src/client/workspaces/service.ts'
|
||||
import { resolvedClientTimeZone } from '../src/client/time-zone.ts'
|
||||
import { FakeApiClient, ok } from './fake-api.ts'
|
||||
|
||||
const CLIENT_TIME_ZONE = resolvedClientTimeZone()
|
||||
|
||||
interface Bench {
|
||||
ctx: Context
|
||||
api: FakeApiClient
|
||||
@@ -105,10 +102,7 @@ describe('runtime client apply', () => {
|
||||
|
||||
const sessions = bench.ctx.get('sessions') as SessionsService
|
||||
const workspaces = bench.ctx.get('workspaces') as WorkspacesService
|
||||
expect(bench.api.callsOf('session.create')).toEqual([{
|
||||
workspaceId: 'w-recent',
|
||||
timeZone: CLIENT_TIME_ZONE,
|
||||
}])
|
||||
expect(bench.api.callsOf('session.create')).toEqual([{ workspaceId: 'w-recent' }])
|
||||
expect(sessions.list.getSnapshot().current).toBe('fk-new')
|
||||
|
||||
sessions.clear()
|
||||
|
||||
@@ -6,13 +6,11 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-client-connection/client'
|
||||
import { SessionManager } from '../src/client/sessions/manager.ts'
|
||||
import { resolvedClientTimeZone } from '../src/client/time-zone.ts'
|
||||
import { FakeApiClient, deferred, err, ok } from './fake-api.ts'
|
||||
import { entries, plainTurn } from './event-script.ts'
|
||||
|
||||
const S1 = 'fk-m1' as SessionId
|
||||
const S2 = 'fk-m2' as SessionId
|
||||
const CLIENT_TIME_ZONE = resolvedClientTimeZone()
|
||||
|
||||
type SummaryOver = Partial<{
|
||||
updatedAt: number
|
||||
@@ -710,11 +708,7 @@ describe('remaining branches', () => {
|
||||
api.onCreate = () => Promise.resolve(ok({ sessionId: S1 }))
|
||||
const manager = new SessionManager(api)
|
||||
await manager.create({ cwd: '/tmp/w', sessionId: S1 })
|
||||
expect(api.callsOf('session.create')).toEqual([{
|
||||
cwd: '/tmp/w',
|
||||
sessionId: S1,
|
||||
timeZone: CLIENT_TIME_ZONE,
|
||||
}])
|
||||
expect(api.callsOf('session.create')).toEqual([{ cwd: '/tmp/w', sessionId: S1 }])
|
||||
expect(manager.getListSnapshot().items[0]).toMatchObject({ sessionId: S1, cwd: '/tmp/w' })
|
||||
await manager.create({ cwd: '/tmp/w' }) // same id returned: no duplicate row
|
||||
expect(manager.getListSnapshot().items).toHaveLength(1)
|
||||
|
||||
@@ -11,7 +11,6 @@ import type { SessionEvent } from '@deepseek-ai/dsh-session/types'
|
||||
import { MAX_TIMER_DELAY_MS } from '@deepseek-ai/dsh-timeout'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-client-connection/client'
|
||||
import { Session } from '../src/client/sessions/session.ts'
|
||||
import { resolvedClientTimeZone } from '../src/client/time-zone.ts'
|
||||
import { FakeApiClient, deferred, err, ok } from './fake-api.ts'
|
||||
import { entries, ev, plainTurn } from './event-script.ts'
|
||||
|
||||
@@ -20,7 +19,6 @@ const at = (seq: number, e: Record<string, unknown>): SessionEvent =>
|
||||
|
||||
const SID = 'fk-s1' as SessionId
|
||||
const PARENT = 'fk-parent' as SessionId
|
||||
const CLIENT_TIME_ZONE = resolvedClientTimeZone()
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals()
|
||||
@@ -724,11 +722,11 @@ describe('prompt and cancel errors', () => {
|
||||
expect(result.ok).toBe(true)
|
||||
// Monotone: settlement alone does not step the phase anywhere.
|
||||
expect(session.getSnapshot().composerPhase).toBe('engaging')
|
||||
expect(api.callsOf('session.prompt')).toEqual([{
|
||||
expect(api.callsOf('session.prompt')).toMatchObject([{
|
||||
sessionId: SID,
|
||||
mode: 'queue',
|
||||
content: [{ type: 'text', text: '要发的' }],
|
||||
clientTimeZone: CLIENT_TIME_ZONE,
|
||||
clientTimeZone: new Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
}])
|
||||
// First content lands (running turn): engaging → active.
|
||||
session.handleRunning(true)
|
||||
|
||||
@@ -10,11 +10,9 @@ import { Context } from 'cordis'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { SessionId } from '@deepseek-ai/dsh-client-connection/client'
|
||||
import { SessionCreateError, SessionsService, scopeOf } from '../src/client/sessions/service.ts'
|
||||
import { resolvedClientTimeZone } from '../src/client/time-zone.ts'
|
||||
import { FakeApiClient, deferred, err, ok } from './fake-api.ts'
|
||||
|
||||
const sid = (s: string): SessionId => s as SessionId
|
||||
const CLIENT_TIME_ZONE = resolvedClientTimeZone()
|
||||
|
||||
interface Bench {
|
||||
ctx: Context
|
||||
@@ -454,11 +452,7 @@ describe('create', () => {
|
||||
const b = bench()
|
||||
b.api.onCreate = () => Promise.resolve(ok({ sessionId: sid('fresh') }))
|
||||
await expect(b.svc.create({ cwd: '/w', sessionId: sid('fresh') })).resolves.toBe('fresh')
|
||||
expect(b.api.callsOf('session.create')).toEqual([{
|
||||
cwd: '/w',
|
||||
sessionId: 'fresh',
|
||||
timeZone: CLIENT_TIME_ZONE,
|
||||
}])
|
||||
expect(b.api.callsOf('session.create')).toEqual([{ cwd: '/w', sessionId: 'fresh' }])
|
||||
b.api.onCreate = () => Promise.resolve({
|
||||
rpcId: 'e' as never,
|
||||
result: { ok: false as const, error: { code: 'internal' as const, message: '爆了', details: {} } },
|
||||
|
||||
@@ -12,11 +12,11 @@ describe('browser time zone', () => {
|
||||
)
|
||||
})
|
||||
|
||||
it('fails loud when the runtime exposes no zone', () => {
|
||||
it.each([undefined, ''])('fails loud when the runtime exposes no zone %#', (timeZone) => {
|
||||
const options = new Intl.DateTimeFormat().resolvedOptions()
|
||||
vi.spyOn(Intl.DateTimeFormat.prototype, 'resolvedOptions').mockReturnValue({
|
||||
...options,
|
||||
timeZone: '',
|
||||
timeZone: timeZone as string,
|
||||
})
|
||||
|
||||
expect(() => resolvedClientTimeZone()).toThrow('browser time zone is unavailable')
|
||||
|
||||
@@ -2,14 +2,12 @@ import { Context } from 'cordis'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import type { SessionId, WorkspaceId, WorkspaceView } from '@deepseek-ai/dsh-client-connection/client'
|
||||
import { SessionsService } from '../src/client/sessions/service.ts'
|
||||
import { resolvedClientTimeZone } from '../src/client/time-zone.ts'
|
||||
import { WorkspaceManager } from '../src/client/workspaces/manager.ts'
|
||||
import { DirectoryBrowseError, WorkspaceCreateError, WorkspacesService } from '../src/client/workspaces/service.ts'
|
||||
import { FakeApiClient, deferred, err, ok } from './fake-api.ts'
|
||||
|
||||
const sid = (id: string): SessionId => id as SessionId
|
||||
const wid = (id: string): WorkspaceId => id as WorkspaceId
|
||||
const CLIENT_TIME_ZONE = resolvedClientTimeZone()
|
||||
|
||||
function workspace(id: string, sessionIds: SessionId[] = [], createdAt = '2026-01-01T00:00:00.000Z'): WorkspaceView {
|
||||
return {
|
||||
@@ -190,10 +188,7 @@ describe('WorkspacesService', () => {
|
||||
// Miss: beta has only a non-blank session → host create with workspaceId.
|
||||
api.onCreate = () => Promise.resolve(ok({ sessionId: sid('s-fresh') }))
|
||||
await expect(workspaces.connectWorkspace(wid('beta'))).resolves.toBe('s-fresh')
|
||||
expect(api.callsOf('session.create')).toEqual([{
|
||||
workspaceId: 'beta',
|
||||
timeZone: CLIENT_TIME_ZONE,
|
||||
}])
|
||||
expect(api.callsOf('session.create')).toEqual([{ workspaceId: 'beta' }])
|
||||
// Same guarantee on the create arm (draft hand-off writes the machine pre-open).
|
||||
expect(sessions.binding(sid('s-fresh'))).toBeDefined()
|
||||
|
||||
@@ -201,10 +196,7 @@ describe('WorkspacesService', () => {
|
||||
// never reused, a fresh accounted session is created instead.
|
||||
api.onCreate = () => Promise.resolve(ok({ sessionId: sid('s-fresh-3') }))
|
||||
await expect(workspaces.connectWorkspace(wid('gamma'))).resolves.toBe('s-fresh-3')
|
||||
expect(api.callsOf('session.create')).toEqual([
|
||||
{ workspaceId: 'beta', timeZone: CLIENT_TIME_ZONE },
|
||||
{ workspaceId: 'gamma', timeZone: CLIENT_TIME_ZONE },
|
||||
])
|
||||
expect(api.callsOf('session.create')).toEqual([{ workspaceId: 'beta' }, { workspaceId: 'gamma' }])
|
||||
|
||||
// Unknown workspace fails loud instead of silently creating in nowhere.
|
||||
await expect(workspaces.connectWorkspace(wid('ghost'))).rejects.toThrow(/unknown workspace ghost/)
|
||||
@@ -419,10 +411,7 @@ describe('startInitialSelection', () => {
|
||||
await b.sessions.refresh()
|
||||
// Store notifications and the connect round trip are microtask-batched.
|
||||
await new Promise(resolve => setTimeout(resolve, 0))
|
||||
expect(b.api.callsOf('session.create')).toEqual([{
|
||||
workspaceId: 'recent',
|
||||
timeZone: CLIENT_TIME_ZONE,
|
||||
}])
|
||||
expect(b.api.callsOf('session.create')).toEqual([{ workspaceId: 'recent' }])
|
||||
expect(b.sessions.list.getSnapshot().current).toBe('s-new')
|
||||
stop()
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user