MCPcopy
hub / github.com/codedogQBY/ReadAny / applyChanges

Function applyChanges

packages/core/src/sync/simple-sync.ts:278–403  ·  view source on GitHub ↗
(
  payload: DeviceSyncPayload,
  options: { forceApply?: boolean } = {},
)

Source from the content-addressed store, hash-verified

276// ---------------------------------------------------------------------------
277
278export async function applyChanges(
279 payload: DeviceSyncPayload,
280 options: { forceApply?: boolean } = {},
281): Promise<{ applied: number; skipped: number }> {
282 return runSerializedDbTask(() =>
283 withDatabaseLockRetry(async () => {
284 await ensureNoTransaction();
285 const db = await getDB();
286 if (shouldRunSyncCleanup()) {
287 await cleanupOrphanedSyncRows(db);
288 }
289 let applied = 0;
290 let skipped = 0;
291
292 // Keep this transaction-free. On some adapters, explicit BEGIN/COMMIT can
293 // lose state across awaited calls and end with "cannot commit - no transaction is active".
294 for (const tableInfo of SYNC_TABLES) {
295 const tableName = tableInfo.name;
296 const tableData = payload.tables[tableName];
297 if (!tableData) continue;
298
299 const { pk, timestampCol } = tableInfo;
300 const exclude = tableInfo.excludeColumns ?? [];
301 console.log(
302 `[SimpleSync] Applying table ${tableName}: ${tableData.records.length} record(s), ${tableData.deletedIds.length} deletion(s)`,
303 );
304 const allIdsToCheck = [
305 ...tableData.records.map((record) => record[pk]).filter((value) => value !== undefined),
306 ...tableData.deletedIds,
307 ];
308 const existingRecords = await loadExistingRecordStates(
309 db,
310 tableName,
311 pk,
312 timestampCol,
313 allIdsToCheck,
314 );
315 const remoteRecordIds = new Set(
316 tableData.records
317 .map((record) => record[pk])
318 .filter((value) => value !== undefined)
319 .map(String),
320 );
321 let processedRecords = 0;
322
323 for (const record of tableData.records) {
324 const pkValue = record[pk];
325 const remoteTs = record[timestampCol] as number;
326
327 const safeRecord =
328 exclude.length > 0
329 ? Object.fromEntries(Object.entries(record).filter(([k]) => !exclude.includes(k)))
330 : record;
331
332 const localState = existingRecords.get(String(pkValue));
333 if (!options.forceApply && !shouldApplyRemoteRecord(record, timestampCol, localState)) {
334 skipped++;
335 } else {

Callers 3

runSimpleSyncFunction · 0.85

Calls 15

runSerializedDbTaskFunction · 0.90
withDatabaseLockRetryFunction · 0.85
ensureNoTransactionFunction · 0.85
getDBFunction · 0.85
shouldRunSyncCleanupFunction · 0.85
cleanupOrphanedSyncRowsFunction · 0.85
loadExistingRecordStatesFunction · 0.85
shouldApplyRemoteRecordFunction · 0.85
upsertRecordFunction · 0.85
normalizeDeletedAtFunction · 0.85
yieldToEventLoopFunction · 0.85

Tested by

no test coverage detected