setup propagates

This commit is contained in:
Shams mosowi
2021-01-10 17:03:53 +08:00
parent ac43497f22
commit 4123c80bf9
5 changed files with 164 additions and 17 deletions

View File

@@ -9,6 +9,7 @@ import {
} from "./functionConfig";
import { getTriggerType } from "./utils";
//import {propagateChangesOnTrigger} from './propagates'
export const FT = {
[functionName]: functions.firestore
@@ -16,24 +17,28 @@ export const FT = {
.onWrite(async (change, context) => {
const triggerType = getTriggerType(change);
let promises: Promise<any>[] = [];
try {
const sparkPromises = sparksConfig
.filter((sparkConfig) => sparkConfig.triggers.includes(triggerType))
.map((sparkConfig) => spark(sparkConfig)(change, context));
console.log(
`#${sparkPromises.length} sparks will be evaluted on ${triggerType}`
const sparkPromises = sparksConfig
.filter((sparkConfig) => sparkConfig.triggers.includes(triggerType))
.map((sparkConfig) => spark(sparkConfig)(change, context));
console.log(
`#${sparkPromises.length} sparks will be evaluted on ${triggerType}`
);
promises = sparkPromises;
if (triggerType !== "delete") {
const derivativePromise = derivative(derivativesConfig)(
change,
context
);
promises = sparkPromises;
} catch (err) {}
promises.push(derivativePromise);
}
// const propagateChanges = propagateChangesOnTrigger(change,triggerType);
// promises.push(propagateChanges);
try {
if (triggerType !== "delete") {
const derivativePromise = derivative(derivativesConfig)(
change,
context
);
promises.push(derivativePromise);
}
} catch (err) {}
await Promise.all(promises);
const result = await Promise.allSettled(promises);
console.log(result);
} catch (err) {
console.log(`caught error: ${err}`);
}
}),
};

View File

@@ -0,0 +1,70 @@
import { DocumentSnapshot } from "firebase-functions/lib/providers/firestore";
import { rowReducer } from "../utils";
const TARGET_SUB_COLLECTION = "_FT_TARGETS";
//sample target sub document
// {collection**}/
/**
{
targetRef:'test/id'
targetFieldKey:'fieldKey'
trackedFields:[]
}
*/
// source changes Trigger
// check and propagate any tracked changes to
export const propagateChanges = (docSnapshot: DocumentSnapshot) =>
docSnapshot.ref
.collection(TARGET_SUB_COLLECTION)
.get()
.then((queryResult) => {
queryResult.docs.map(async (doc) => {
const { targetRef, targetFieldKey, trackedFields } = doc.data() as {
targetRef: FirebaseFirestore.DocumentReference;
targetFieldKey: string;
trackedFields: string[];
};
const targetDoc = await targetRef.get();
if (!targetDoc.exists) return false;
const targetFieldValue = targetDoc.get(targetFieldKey);
const indexOfCurrentTarget = targetFieldValue.findIndex(
(element) => element.docPath === docSnapshot.ref.path
);
if (indexOfCurrentTarget > -1) {
targetFieldValue[indexOfCurrentTarget].snapshot = rowReducer(
trackedFields,
docSnapshot.data()
);
await targetRef.update({ [targetFieldKey]: targetFieldValue });
return true;
} else return false;
});
});
// when deleting a document all snapshot copies of it in
export const removeCopiesOfDeleteDoc = (
sourceDocRef: FirebaseFirestore.DocumentReference
) =>
sourceDocRef
.collection(TARGET_SUB_COLLECTION)
.get()
.then((queryResult) => {
queryResult.docs.map(async (doc) => {
const { targetRef, targetFieldKey } = doc.data() as {
targetRef: FirebaseFirestore.DocumentReference;
targetFieldKey: string;
};
const targetDoc = await targetRef.get();
const currentTargetFieldValue = targetDoc.get(targetFieldKey);
const newTargetFieldValue = currentTargetFieldValue.filter(
({ docPath }: { docPath: string; snapshot: any }) =>
docPath !== sourceDocRef.path
);
await targetRef.update({ [targetFieldKey]: newTargetFieldValue });
await doc.ref.delete();
});
});

View File

@@ -0,0 +1,48 @@
import { db } from "../firebaseConfig";
const TARGET_SUB_COLLECTION = "_FT_TARGETS";
//sample target sub document
// {collection**}/
/**
{
targetRef:'test/id'
targetFieldKey:'fieldKey'
trackedFields:[]
}
*/
// Target changes Trigger
// add propagation reference from source subcollection
export const addTargetRef = (
targetRef: FirebaseFirestore.DocumentReference,
sourceDocPath: string,
targetFieldKey: string,
trackedFields
) =>
db
.collection(`${sourceDocPath}/${TARGET_SUB_COLLECTION}`)
.add({ targetRef, targetFieldKey, trackedFields });
// remove propagation reference from source subcollection
export const removeTargetRef = (
targetRef: FirebaseFirestore.DocumentReference,
sourceDocPath: string
) =>
db
.collection(`${sourceDocPath}/${TARGET_SUB_COLLECTION}`)
.where("targetRef", "==", targetRef)
.get()
.then((queryResult) => queryResult.docs.map((doc) => doc.ref.delete()));
// removes all references of deleted targets
export const removeAllReferencesOnTargetDelete = (
targetDocRef: FirebaseFirestore.DocumentReference
) =>
db
.collectionGroup(TARGET_SUB_COLLECTION)
.where("targetRef", "==", targetDocRef)
.get()
.then((queryResult) => queryResult.docs.map((doc) => doc.ref.delete()));

View File

@@ -0,0 +1,17 @@
import * as functions from "firebase-functions";
import { propagateChanges, removeCopiesOfDeleteDoc } from "./SourceFns";
export const propagateChangesOnTrigger = (
change: functions.Change<functions.firestore.DocumentSnapshot>,
triggerType: "delete" | "create" | "update"
) => {
switch (triggerType) {
case "update":
return propagateChanges(change.after);
case "delete":
return removeCopiesOfDeleteDoc(change.before.ref);
case "create":
default:
return new Promise(() => false);
}
};

View File

@@ -46,6 +46,13 @@ export const getTriggerType = (change) =>
? "create"
: "delete";
export const rowReducer = (fieldsToSync, row) =>
fieldsToSync.reduce((acc: any, curr: string) => {
if (row[curr] !== undefined && row[curr] !== null)
return { ...acc, [curr]: row[curr] };
else return acc;
}, {});
export default {
getSecret,
hasRequiredFields,