Improve OpenChamber responsiveness under large session workloads while fixing cache, synchronization, and persistence correctness across runtimes, projects, directories, and worktrees. - prioritize selected and visible sessions during bootstrap and defer non-critical enrichment work - reduce redundant message loading, event processing, store publication, and hidden sidebar work - prevent stale session and message requests from overwriting newer authoritative state - preserve existing data when authoritative fetches fail instead of treating failures as successful empty responses - scope session materialization, messages, drafts, queues, todos, pins, permissions, folders, tabs, Git state, and pull request data by runtime and directory identity - harden runtime switching, reconnect, cleanup, mutation reconciliation, and persisted-state ordering - preserve live subagent Task linkage when metadata arrives after an older message request or while streaming parts are suspended - coalesce overlapping tail refreshes without losing newer refresh demand - improve cold-session loading by moving deferrable work out of the critical bootstrap path - isolate URL authentication, mobile credentials, native secrets, and other runtime-owned state across endpoint changes - bound long-lived caches and remove avoidable allocations from event and rendering hot paths - limit virtualization to archive collections where it improves rendering without disrupting active sidebar layout - stabilize session folders, pin ordering, expanded state, and persisted sidebar behavior - open skill files through the same secure editor and outside-workspace grant flow used by file navigation, including worktree sessions - expand regression coverage for stale completions, runtime collisions, reconnect behavior, persistence races, authoritative empty results, and subagent refresh ordering - document the updated synchronization, cache ownership, performance, and runtime-isolation invariants
127 lines
3.9 KiB
TypeScript
127 lines
3.9 KiB
TypeScript
const STORAGE_KEY = "openchamber_sync_perf"
|
|
|
|
declare global {
|
|
interface Window {
|
|
__openchamberSyncPerformance?: {
|
|
getSnapshot: () => SyncPerformanceCounters | null
|
|
reset: () => void
|
|
}
|
|
}
|
|
}
|
|
|
|
export type SyncPerformanceCounters = {
|
|
pipelineRawEvents: number
|
|
pipelineCoalescedEvents: number
|
|
pipelineDeliveredEvents: number
|
|
reducerEvents: number
|
|
reducerChangedEvents: number
|
|
directoryStorePublications: number
|
|
streamingFullReconciliations: number
|
|
streamingIncrementalReconciliations: number
|
|
streamingStatusEntriesVisited: number
|
|
streamingSessionCandidatesVisited: number
|
|
streamingMessagesVisited: number
|
|
streamingHeartbeatAttempts: number
|
|
streamingHeartbeatCommits: number
|
|
permissionChangeCallbacks: number
|
|
sessionMessageChangeCallbacks: number
|
|
sessionRenderableNotificationSkips: number
|
|
userMessageHistoryNotificationSkips: number
|
|
sessionMessageRecordNotificationSkips: number
|
|
materializationEnqueues: number
|
|
materializationEmptyAssistantEnqueues: number
|
|
materializationMissingMessageEnqueues: number
|
|
materializationMissingPartEnqueues: number
|
|
materializationLifecycleEnqueues: number
|
|
materializationPreflightSkips: number
|
|
materializationRequests: number
|
|
statusAggregationSessionEntries: number
|
|
statusAggregationCandidates: number
|
|
persistenceSerializations: number
|
|
persistenceStorageWrites: number
|
|
persistenceUtf8Bytes: number
|
|
}
|
|
|
|
const createCounters = (): SyncPerformanceCounters => ({
|
|
pipelineRawEvents: 0,
|
|
pipelineCoalescedEvents: 0,
|
|
pipelineDeliveredEvents: 0,
|
|
reducerEvents: 0,
|
|
reducerChangedEvents: 0,
|
|
directoryStorePublications: 0,
|
|
streamingFullReconciliations: 0,
|
|
streamingIncrementalReconciliations: 0,
|
|
streamingStatusEntriesVisited: 0,
|
|
streamingSessionCandidatesVisited: 0,
|
|
streamingMessagesVisited: 0,
|
|
streamingHeartbeatAttempts: 0,
|
|
streamingHeartbeatCommits: 0,
|
|
permissionChangeCallbacks: 0,
|
|
sessionMessageChangeCallbacks: 0,
|
|
sessionRenderableNotificationSkips: 0,
|
|
userMessageHistoryNotificationSkips: 0,
|
|
sessionMessageRecordNotificationSkips: 0,
|
|
materializationEnqueues: 0,
|
|
materializationEmptyAssistantEnqueues: 0,
|
|
materializationMissingMessageEnqueues: 0,
|
|
materializationMissingPartEnqueues: 0,
|
|
materializationLifecycleEnqueues: 0,
|
|
materializationPreflightSkips: 0,
|
|
materializationRequests: 0,
|
|
statusAggregationSessionEntries: 0,
|
|
statusAggregationCandidates: 0,
|
|
persistenceSerializations: 0,
|
|
persistenceStorageWrites: 0,
|
|
persistenceUtf8Bytes: 0,
|
|
})
|
|
|
|
const readInitialEnabled = (): boolean => {
|
|
if (typeof window === "undefined") return false
|
|
try {
|
|
return window.localStorage.getItem(STORAGE_KEY) === "1"
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
let activeCounters: SyncPerformanceCounters | null = readInitialEnabled() ? createCounters() : null
|
|
|
|
export function setSyncPerformanceDiagnosticsEnabled(enabled: boolean): void {
|
|
activeCounters = enabled ? createCounters() : null
|
|
}
|
|
|
|
export function resetSyncPerformanceDiagnostics(): void {
|
|
if (activeCounters) activeCounters = createCounters()
|
|
}
|
|
|
|
export function getSyncPerformanceDiagnostics(): SyncPerformanceCounters | null {
|
|
return activeCounters ? { ...activeCounters } : null
|
|
}
|
|
|
|
export function countSyncPerformance(
|
|
counter: keyof SyncPerformanceCounters,
|
|
amount = 1,
|
|
): void {
|
|
const counters = activeCounters
|
|
if (!counters) return
|
|
counters[counter] += amount
|
|
}
|
|
|
|
export function countSyncPersistenceSerialization(serialized: string): void {
|
|
const counters = activeCounters
|
|
if (!counters) return
|
|
counters.persistenceSerializations += 1
|
|
counters.persistenceUtf8Bytes += new TextEncoder().encode(serialized).byteLength
|
|
}
|
|
|
|
export function countSyncPersistenceStorageWrite(): void {
|
|
if (activeCounters) activeCounters.persistenceStorageWrites += 1
|
|
}
|
|
|
|
if (typeof window !== "undefined") {
|
|
window.__openchamberSyncPerformance = {
|
|
getSnapshot: getSyncPerformanceDiagnostics,
|
|
reset: resetSyncPerformanceDiagnostics,
|
|
}
|
|
}
|