UNPKG

@genkit-ai/firebase

Version:

Genkit AI framework plugin for Firebase including Firestore trace/state store and deployment helpers for Cloud Functions for Firebase.

133 lines 4.25 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var firestore_exports = {}; __export(firestore_exports, { FirestoreStreamManager: () => FirestoreStreamManager }); module.exports = __toCommonJS(firestore_exports); var import_crypto = require("crypto"); var import_firestore = require("firebase-admin/firestore"); var import_beta = require("genkit/beta"); class FirestoreActionStream { streamDoc; constructor(streamDoc) { this.streamDoc = streamDoc; } async update(data) { await this.streamDoc.update({ ...data, updatedAt: import_firestore.FieldValue.serverTimestamp() }); } async write(chunk) { await this.update({ // We add a random ID to the chunk to prevent Firestore from deduplicating chunks // that have the same content. stream: import_firestore.FieldValue.arrayUnion({ type: "chunk", chunk, uuid: (0, import_crypto.randomUUID)() }) }); } async done(output) { await this.update({ stream: import_firestore.FieldValue.arrayUnion({ type: "done", output }) }); } async error(err) { const serializableError = { message: err.message, stack: err.stack, ...err }; await this.update({ stream: import_firestore.FieldValue.arrayUnion({ type: "error", err: serializableError }) }); } } class FirestoreStreamManager { db; collection; timeout; constructor(opts) { this.collection = opts.collection; this.db = opts.db ?? (opts.firebaseApp ? (0, import_firestore.getFirestore)(opts.firebaseApp) : (0, import_firestore.getFirestore)()); this.timeout = opts.timeout ?? 6e4; } async open(streamId) { const streamDoc = this.db.collection(this.collection).doc(streamId); await streamDoc.set({ createdAt: import_firestore.FieldValue.serverTimestamp(), stream: [] }); return new FirestoreActionStream(streamDoc); } async subscribe(streamId, callbacks) { const streamDoc = this.db.collection(this.collection).doc(streamId); const snapshot = await streamDoc.get(); if (!snapshot.exists) { throw new import_beta.StreamNotFoundError(`Stream ${streamId} not found.`); } let lastIndex = -1; let timeoutId; const resetTimeout = () => { clearTimeout(timeoutId); timeoutId = setTimeout(() => { callbacks.onError?.( new import_beta.GenkitError({ status: "DEADLINE_EXCEEDED", message: "Stream timed out." }) ); unsubscribe(); }, this.timeout); }; const unsubscribe = streamDoc.onSnapshot((snapshot2) => { resetTimeout(); const data = snapshot2.data(); if (!data) { return; } const stream = data.stream || []; for (let i = lastIndex + 1; i < stream.length; i++) { const event = stream[i]; if (event.type === "chunk") { callbacks.onChunk?.(event.chunk); } else if (event.type === "done") { clearTimeout(timeoutId); callbacks.onDone?.(event.output); unsubscribe(); } else if (event.type === "error") { clearTimeout(timeoutId); callbacks.onError?.(event.err); unsubscribe(); } } lastIndex = stream.length - 1; }); resetTimeout(); return { unsubscribe }; } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { FirestoreStreamManager }); //# sourceMappingURL=firestore.js.map