Sync Runner
Reusable pattern for synchronizing data from external systems (ERP, PIM, etc.).
Defining a Sync Job
import { type SyncJob } from "$lib/server/integrations";
const inventorySync: SyncJob<ErpItem, LocalVariant> = {
name: "erp-inventory",
// Fetch all items from external system
fetchExternal: () => erpClient.getInventory(),
// Get unique identifier
getExternalId: (item) => item.sku,
// Find matching local record
findLocal: async (sku) => {
const [variant] = await db.select().from(variants).where(eq(variants.sku, sku));
return variant ?? null;
},
// Create new record
create: async (item) => {
await db.insert(variants).values({
sku: item.sku,
stock: item.quantity
});
},
// Update existing record
update: async (item, local) => {
await db.update(variants).set({ stock: item.quantity }).where(eq(variants.id, local.id));
},
// Optional hooks
onStart: async () => console.log("Starting sync"),
onComplete: async (results) => console.log("Done:", results)
};Running Syncs
Immediately
import { runSync } from "$lib/server/integrations";
const results = await runSync(inventorySync);
// {
// name: 'erp-inventory',
// created: 10,
// updated: 45,
// errors: [],
// durationMs: 1234
// }Via Workflow (Scheduled)
workflows/erp-sync.ts
import { sleep } from "workflow";
export async function erpInventorySync() {
"use workflow";
while (true) {
await syncStep();
await sleep("1h");
}
}
async function syncStep() {
"use step";
const { runSync } = await import("$lib/server/integrations");
await runSync(inventorySync);
}Single Item Sync
For webhook-triggered updates:
import { syncSingleItem } from "$lib/server/integrations";
// When webhook receives inventory update
const result = await syncSingleItem(inventorySync, webhookPayload);
// { action: 'updated', externalId: 'SKU-001' }Error Handling
Errors are collected per item without stopping the sync:
const results = await runSync(mySync);
if (results.errors.length > 0) {
for (const error of results.errors) {
console.error(`Failed: ${error.externalId}`, error.message);
}
}Last updated on