Last active
November 3, 2024 01:54
-
-
Save maietta/d4f7b75d5117c1739fe6af7addeeddf4 to your computer and use it in GitHub Desktop.
Watch for events on Pocketbase
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import PocketBase from "pocketbase"; | |
import eventsource from "eventsource"; | |
global.EventSource = eventsource as unknown as typeof EventSource; | |
const pb = new PocketBase(process.env.POCKETBASE_URL); | |
// Store the initial states of all records in a cache | |
const previousRecords: { [recordId: string]: any } = {}; | |
async function watchCollectionChanges(collection: string) { | |
// Optionally, pre-cache initial states of all records | |
const initialRecords = await pb.collection(collection).getFullList(); | |
// Populate previousRecords cache | |
initialRecords.forEach(record => { | |
previousRecords[record.id] = record; | |
}); | |
// Subscribe to real-time updates on all records in the collection | |
pb.collection(collection).subscribe("*", (e) => { | |
const updatedRecord = e.record; | |
if (e.action === "update" || e.action === "create") { | |
const recordId = updatedRecord.id; | |
const previousRecord = previousRecords[recordId] || {}; | |
// Compare fields to detect changes | |
Object.keys(updatedRecord).forEach((field) => { | |
// Ignore `created`, `updated`, and `id` fields | |
if (["created", "updated", "id"].includes(field)) { | |
return; | |
} | |
switch (field) { | |
case "data": | |
case "photos": | |
if (updatedRecord[field] === null && previousRecord[field] === null) return; | |
// Handle `data` field logic here | |
if (field === "data" && updatedRecord[field] !== previousRecord[field]) { | |
if (updatedRecord[field] === null && previousRecord[field] !== null) { | |
console.log(`Record ID: ${recordId} - New record created.`); | |
return; | |
} else if (previousRecord[field] === null) { | |
console.log(`Record ID: ${recordId} - Record updated.`); | |
return; | |
} else { | |
const differences: string[] = []; | |
// Compare JSON objects | |
if (typeof updatedRecord[field] === "object" && typeof previousRecord[field] === "object") { | |
for (const key in updatedRecord[field]) { | |
if (Object.prototype.hasOwnProperty.call(updatedRecord[field], key)) { | |
if (updatedRecord[field][key] !== previousRecord[field][key]) { | |
differences.push(`${key}: ${previousRecord[field][key]} -> ${updatedRecord[field][key]}`); | |
} | |
} | |
} | |
} | |
if (differences.length > 0) { | |
if (differences.some((diff) => diff.includes("L_Photo_Updt_Date"))) { | |
console.log(`Time to update photos for record ID: ${recordId}.`); | |
//return; | |
} | |
console.log(`Record ID: ${recordId} - Field "${field}" changed: ${differences.join(", ")}`); | |
} | |
} | |
} | |
break; | |
case "class": | |
if (updatedRecord[field] !== previousRecord[field]) { | |
if (previousRecord[field] === undefined && updatedRecord[field] === "") return; | |
console.log(`Record ID: ${recordId} - Class Type changed from ${previousRecord[field]} to ${updatedRecord[field]}`); | |
} | |
break; | |
default: | |
if (updatedRecord[field] !== previousRecord[field]) { | |
console.log(`Record ID: ${recordId} - Field "${field}" changed from ${previousRecord[field]} to ${updatedRecord[field]}`); | |
} | |
break; | |
} | |
}); | |
// Update the cache for this record | |
previousRecords[recordId] = updatedRecord; | |
} | |
if (e.action === "delete") { | |
console.log(`Record ID: ${e.record.id} was deleted.`); | |
delete previousRecords[e.record.id]; | |
} | |
}); | |
} | |
// Use the function to watch an entire collection | |
watchCollectionChanges("listings"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment