UNPKG

firestore-queue

Version:

A powerful, scalable queue system built on Google Firestore with time-based indexing, auto-configuration, and connection reuse

309 lines (292 loc) 8.87 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CloudFunctionWriter = void 0; const FirestoreWriter_1 = require("./FirestoreWriter"); /** * Cloud Function Writer for Fire Queue * Integrates with Google Cloud Functions for automatic queue writing */ class CloudFunctionWriter { constructor(config) { this.config = { region: 'us-central1', triggerType: 'firestore', ...config, }; // Use FirestoreWriter as the underlying writer this.firestoreWriter = new FirestoreWriter_1.FirestoreWriter(config); } /** * Write message (delegates to FirestoreWriter) */ async write(message) { return this.firestoreWriter.write(message); } /** * Write batch (delegates to FirestoreWriter) */ async writeBatch(messages) { return this.firestoreWriter.writeBatch(messages); } /** * Generate Cloud Function code for automatic queue writing */ generateCloudFunction() { switch (this.config.triggerType) { case 'firestore': return this.generateFirestoreTrigger(); case 'http': return this.generateHTTPTrigger(); case 'schedule': return this.generateScheduleTrigger(); default: throw new Error(`Unsupported trigger type: ${this.config.triggerType}`); } } /** * Generate Firestore trigger function */ generateFirestoreTrigger() { return ` import { onDocumentWritten } from 'firebase-functions/v2/firestore'; import { FirestoreWriter } from 'fire-queue'; const queueWriter = new FirestoreWriter({ queueName: '${this.config.queueName}', projectId: '${this.config.projectId}', databaseId: '${this.config.databaseId || '(default)'}', enableBatching: true, batchSize: 50, batchTimeoutMs: 30000, // 30 seconds }); /** * Auto-generated Fire Queue writer function * Triggers on Firestore document changes and queues them for processing */ export const queueDocumentChanges = onDocumentWritten({ document: '{collection}/{docId}', // Configure your document path region: '${this.config.region}', }, async (event) => { const change = event.data; const docId = event.params.docId; if (!change) return; try { // Determine operation type let operation: 'CREATE' | 'UPDATE' | 'DELETE'; let data: any; if (!change.before?.exists && change.after?.exists) { operation = 'CREATE'; data = change.after.data(); } else if (change.before?.exists && !change.after?.exists) { operation = 'DELETE'; data = change.before.data(); } else { operation = 'UPDATE'; data = change.after?.data(); } // Queue the change await queueWriter.write({ type: 'document_change', payload: { docId, operation, data, collection: event.params.collection || 'unknown', }, priority: operation === 'DELETE' ? 1 : 3, tags: [operation.toLowerCase(), 'auto-generated'], metadata: { source: 'firestore-trigger', functionName: '${this.config.functionName}', timestamp: new Date().toISOString(), }, }); console.log(\`Queued \${operation} for document \${docId}\`); } catch (error) { console.error('Failed to queue document change:', error); } }); `; } /** * Generate HTTP trigger function */ generateHTTPTrigger() { return ` import { onRequest } from 'firebase-functions/v2/https'; import { FirestoreWriter } from 'fire-queue'; const queueWriter = new FirestoreWriter({ queueName: '${this.config.queueName}', projectId: '${this.config.projectId}', databaseId: '${this.config.databaseId || '(default)'}', validatePayload: true, maxPayloadSize: 1024 * 1024, // 1MB }); /** * Auto-generated Fire Queue HTTP writer function * Accepts HTTP requests and queues them for processing */ export const queueHTTPRequests = onRequest({ region: '${this.config.region}', cors: true, }, async (req, res) => { // Only allow POST requests if (req.method !== 'POST') { res.status(405).json({ error: 'Method not allowed' }); return; } try { const { message, messages } = req.body; if (message) { // Single message const result = await queueWriter.write({ ...message, metadata: { ...message.metadata, source: 'http-trigger', userAgent: req.get('User-Agent'), ip: req.ip, timestamp: new Date().toISOString(), }, }); res.json(result); } else if (messages && Array.isArray(messages)) { // Batch messages const result = await queueWriter.writeBatch( messages.map(msg => ({ ...msg, metadata: { ...msg.metadata, source: 'http-trigger', userAgent: req.get('User-Agent'), ip: req.ip, timestamp: new Date().toISOString(), }, })) ); res.json(result); } else { res.status(400).json({ error: 'Either message or messages array is required' }); } } catch (error) { console.error('HTTP queue write failed:', error); res.status(500).json({ error: error.message }); } }); `; } /** * Generate scheduled trigger function */ generateScheduleTrigger() { return ` import { onSchedule } from 'firebase-functions/v2/scheduler'; import { FirestoreWriter } from 'fire-queue'; const queueWriter = new FirestoreWriter({ queueName: '${this.config.queueName}', projectId: '${this.config.projectId}', databaseId: '${this.config.databaseId || '(default)'}', enableBatching: true, batchSize: 100, }); /** * Auto-generated Fire Queue scheduled writer function * Runs on schedule and queues periodic tasks */ export const queueScheduledTasks = onSchedule({ schedule: '${this.config.schedule || 'every 5 minutes'}', region: '${this.config.region}', }, async () => { console.log('Scheduled queue writer triggered'); try { // Example: Queue periodic maintenance tasks const tasks = [ { type: 'maintenance', payload: { task: 'cleanup_expired_data', schedule: '${this.config.schedule}', }, priority: 5, tags: ['maintenance', 'scheduled'], }, { type: 'health_check', payload: { task: 'system_health_check', timestamp: Date.now(), }, priority: 3, tags: ['health', 'monitoring'], }, ]; const result = await queueWriter.writeBatch(tasks); console.log(\`Queued \${result.successfulWrites} scheduled tasks\`); } catch (error) { console.error('Scheduled queue write failed:', error); } }); `; } /** * Generate deployment configuration */ generateDeploymentConfig() { return { functions: { [this.config.functionName]: { source: './functions', runtime: 'nodejs18', region: this.config.region, environmentVariables: { FIRE_QUEUE_PROJECT_ID: this.config.projectId, FIRE_QUEUE_NAME: this.config.queueName, FIRE_QUEUE_DATABASE_ID: this.config.databaseId || '(default)', }, ...(this.config.triggerType === 'schedule' && { schedule: this.config.schedule, }), }, }, }; } /** * Generate package.json for Cloud Function */ generatePackageJson() { return { name: `fire-queue-${this.config.functionName}`, version: '1.0.0', description: `Auto-generated Fire Queue writer function: ${this.config.functionName}`, main: 'lib/index.js', scripts: { build: 'tsc', deploy: 'npm run build && firebase deploy --only functions', serve: 'npm run build && firebase emulators:start --only functions', }, dependencies: { 'firebase-functions': '^4.0.0', 'firebase-admin': '^12.0.0', 'fire-queue': '^0.1.0', }, devDependencies: { typescript: '^5.0.0', '@types/node': '^20.0.0', }, engines: { node: '18', }, }; } /** * Close writer */ async close() { await this.firestoreWriter.close(); } } exports.CloudFunctionWriter = CloudFunctionWriter; //# sourceMappingURL=CloudFunctionWriter.js.map