Implement replay-safe browser synchronization
This commit is contained in:
parent
06a7ac56b7
commit
459ffa04c6
1 changed files with 2734 additions and 25 deletions
93
web/src/sync/test-fixtures.ts
Normal file
93
web/src/sync/test-fixtures.ts
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
import type { EventFrameDto, JobDto, ProgressDto } from '../api/contracts'
|
||||
|
||||
export const observedAt = '2026-07-17T00:00:00Z'
|
||||
|
||||
export function job(revision: number, overrides: Partial<JobDto> = {}): JobDto {
|
||||
return {
|
||||
resource_kind: 'job',
|
||||
id: 'job_00000001',
|
||||
owner: 'owner_000001',
|
||||
label: 'Fixture job',
|
||||
revision,
|
||||
phase: 'Running',
|
||||
lifecycle: 'visible',
|
||||
source: {
|
||||
kind: 'http',
|
||||
display_url: 'https://example.invalid/archive',
|
||||
result_path: 'archive.bin',
|
||||
},
|
||||
target: {
|
||||
store: 'target-main',
|
||||
bucket: 'fixture-bucket',
|
||||
prefix: 'results',
|
||||
},
|
||||
authoritative_attempt: {
|
||||
attempt_id: 'attempt_0001',
|
||||
fence: 1,
|
||||
worker_incarnation: 'worker_00001',
|
||||
},
|
||||
progress: progress(10),
|
||||
checkpoint: null,
|
||||
result: null,
|
||||
failure: null,
|
||||
created_at: observedAt,
|
||||
updated_at: observedAt,
|
||||
event_cursor: 'cursor-snapshot-0001',
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
export function progress(completedBytes: number): ProgressDto {
|
||||
return {
|
||||
attempt_id: 'attempt_0001',
|
||||
fence: 1,
|
||||
completed_bytes: completedBytes,
|
||||
total_bytes: 100,
|
||||
completed_members: 0,
|
||||
total_members: 1,
|
||||
observed_at: observedAt,
|
||||
}
|
||||
}
|
||||
|
||||
export function jobChanged(
|
||||
sequence: number,
|
||||
eventId: string,
|
||||
revision: number,
|
||||
completedBytes: number,
|
||||
): EventFrameDto {
|
||||
return {
|
||||
schema_version: 1,
|
||||
kind: 'job_changed',
|
||||
event_id: eventId,
|
||||
sequence,
|
||||
cursor: `cursor-event-${String(sequence).padStart(4, '0')}`,
|
||||
occurred_at: observedAt,
|
||||
job_id: 'job_00000001',
|
||||
job_revision: revision,
|
||||
phase: 'Running',
|
||||
lifecycle: 'visible',
|
||||
authoritative_attempt: {
|
||||
attempt_id: 'attempt_0001',
|
||||
fence: 1,
|
||||
},
|
||||
progress: {
|
||||
attempt_id: 'attempt_0001',
|
||||
fence: 1,
|
||||
completed_bytes: completedBytes,
|
||||
total_bytes: 100,
|
||||
completed_members: 0,
|
||||
total_members: 1,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function heartbeat(sequence: number, eventId: string): EventFrameDto {
|
||||
return {
|
||||
schema_version: 1,
|
||||
kind: 'heartbeat',
|
||||
event_id: eventId,
|
||||
sequence,
|
||||
cursor: `cursor-event-${String(sequence).padStart(4, '0')}`,
|
||||
occurred_at: observedAt,
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue