@magnetarjs/plugin-firestore-admin
Version:
Magnetar plugin firestore-admin
79 lines (78 loc) • 3.48 kB
JavaScript
import { deleteActionFactory } from './actions/delete.js';
import { deletePropActionFactory } from './actions/deleteProp.js';
import { fetchActionFactory } from './actions/fetch.js';
import { fetchAggregateActionFactory } from './actions/fetchAggregate.js';
import { fetchCountActionFactory } from './actions/fetchCount.js';
import { insertActionFactory } from './actions/insert.js';
import { writeActionFactory } from './actions/mergeAssignReplace.js';
import { revertActionFactory } from './actions/revert.js';
import { streamActionFactory } from './actions/stream.js';
function firestorePluginOptionsWithDefaults(firestorePluginOptions) {
return {
syncDebounceMs: 1000,
useModulePathsForFirestore: true,
debug: false,
...firestorePluginOptions,
};
}
// a Magnetar plugin is a single function that returns a `PluginInstance`
// the plugin implements the logic for all actions that a can be called from a Magnetar module instance
// each action must have the proper for both collection and doc type modules
/**
* It's required to pass the Firestore instance to make sure there are not two separate instances running which can cause issues.
* As long as Firebase is initialized before you pass it, you can just import and pass it like so:
* @example
* ```js
* import { initializeApp } from 'firebase/app'
* import { getFirestore } from 'firebase-admin/firestore'
* import { CreatePlugin as FirestorePlugin } from '@magnetarjs/firestore'
*
* const firebaseApp = initializeApp({ }) // pass config
* const db = getFirestore(firebaseApp)
*
* // initialise plugin
* const remote = FirestorePlugin({ db })
* ```
*/
export const CreatePlugin = (firestorePluginOptions) => {
const pluginOptions = firestorePluginOptionsWithDefaults(firestorePluginOptions);
/** A map with the `collectionPath` as key and a `BatchSync` instance as value */
const batchSyncMap = new Map();
async function syncPendingWrites() {
const promises = [];
for (const [_path, batchSync] of batchSyncMap) {
if (batchSync)
promises.push(batchSync.forceSyncEarly());
}
await Promise.all(promises);
}
// the plugin must try to implement logic for every `ActionName`
const fetch = fetchActionFactory(pluginOptions);
const fetchCount = fetchCountActionFactory(pluginOptions);
const fetchSum = fetchAggregateActionFactory('sum', pluginOptions);
const fetchAverage = fetchAggregateActionFactory('average', pluginOptions);
const stream = streamActionFactory(pluginOptions);
const insert = insertActionFactory(batchSyncMap, pluginOptions);
const _merge = writeActionFactory(batchSyncMap, pluginOptions, 'merge');
const assign = writeActionFactory(batchSyncMap, pluginOptions, 'assign');
const replace = writeActionFactory(batchSyncMap, pluginOptions, 'replace');
const deleteProp = deletePropActionFactory(batchSyncMap, pluginOptions);
const _delete = deleteActionFactory(batchSyncMap, pluginOptions);
const actions = {
fetch,
fetchCount,
fetchSum,
fetchAverage,
stream,
insert,
merge: _merge,
assign,
replace,
deleteProp,
delete: _delete,
};
const revert = revertActionFactory(actions, pluginOptions);
// the plugin function must return a `PluginInstance`
const instance = { revert, actions, syncPendingWrites };
return instance;
};