refactor(sdk): split hooks, dsr-portal, provider, sync approaching 500 LOC

All four files split into focused sibling modules so every file lands
comfortably under the 300-LOC soft target (hard cap 500):

  hooks.ts (474→43)  → hooks-core / hooks-dsgvo / hooks-compliance
                        hooks-rag-security / hooks-ui
  dsr-portal.ts (464→129) → dsr-portal-translations / dsr-portal-render
  provider.tsx (462→247)  → provider-effects / provider-callbacks
  sync.ts (435→299)       → sync-storage / sync-conflict

Zero behaviour changes. All public APIs remain importable from the
original paths (hooks.ts re-exports every hook, provider.tsx keeps all
named exports, sync.ts preserves StateSyncManager + factory).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-04-18 08:40:20 +02:00
parent 19d6437161
commit 9ecd3b2d84
15 changed files with 1700 additions and 1299 deletions
@@ -0,0 +1,67 @@
/**
* Conflict resolution helpers for StateSyncManager.
*
* Extracted from sync.ts to stay within the 300-LOC target.
*/
import type { SDKState, ConflictResolution } from '@breakpilot/compliance-sdk-types'
// =============================================================================
// DEFAULT CONFLICT HANDLER
// =============================================================================
/**
* Default strategy: if local is newer, keep local; otherwise merge
* server as the base but preserve local preferences and deduplicate
* commandBarHistory / recentSearches.
*/
export async function defaultConflictHandler(
local: SDKState,
server: SDKState
): Promise<ConflictResolution> {
const localTime = new Date(local.lastModified).getTime()
const serverTime = new Date(server.lastModified).getTime()
if (localTime > serverTime) {
return { strategy: 'local' }
}
const mergedState: SDKState = {
...server,
preferences: local.preferences,
commandBarHistory: [
...local.commandBarHistory,
...server.commandBarHistory.filter(
h => !local.commandBarHistory.some(lh => lh.id === h.id)
),
].slice(0, 50),
recentSearches: [...new Set([...local.recentSearches, ...server.recentSearches])].slice(
0,
20
),
}
return { strategy: 'merge', mergedState }
}
// =============================================================================
// CONFLICT RESOLUTION APPLIER
// =============================================================================
/**
* Given a resolution strategy and both states, returns the winning state.
*/
export function applyConflictResolution(
resolution: ConflictResolution,
localState: SDKState,
serverState: SDKState
): SDKState {
switch (resolution.strategy) {
case 'local':
return localState
case 'server':
return serverState
case 'merge':
return resolution.mergedState || localState
}
}