🔧 fix: Apply Mongoose Plugin at Model Creation (#7749)

* fix: apply mongoMeili when models are created to use main runtime mongoose

* chore: update @librechat/data-schemas version to 0.0.8

* refactor: remove unused useDebounceCodeBlock

* fix: ensure setter function is stable and handle numeric conversion in useDebouncedInput

* refactor: replace useCallback with useMemo for stable debounced function in useDebouncedInput
This commit is contained in:
Danny Avila 2025-06-04 23:11:34 -04:00 committed by GitHub
parent be4cf5846c
commit dff4fcac00
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 40 additions and 73 deletions

View file

@ -1,6 +1,6 @@
{
"name": "@librechat/data-schemas",
"version": "0.0.7",
"version": "0.0.8",
"description": "Mongoose schemas and models for LibreChat",
"type": "module",
"main": "dist/index.cjs",

View file

@ -1,10 +1,21 @@
import type * as t from '~/types';
import mongoMeili from '~/models/plugins/mongoMeili';
import convoSchema from '~/schema/convo';
/**
* Creates or returns the Conversation model using the provided mongoose instance and schema
*/
export function createConversationModel(mongoose: typeof import('mongoose')) {
if (process.env.MEILI_HOST && process.env.MEILI_MASTER_KEY) {
convoSchema.plugin(mongoMeili, {
mongoose,
host: process.env.MEILI_HOST,
apiKey: process.env.MEILI_MASTER_KEY,
/** Note: Will get created automatically if it doesn't exist already */
indexName: 'convos',
primaryKey: 'conversationId',
});
}
return (
mongoose.models.Conversation || mongoose.model<t.IConversation>('Conversation', convoSchema)
);

View file

@ -1,9 +1,20 @@
import messageSchema from '~/schema/message';
import type * as t from '~/types';
import mongoMeili from '~/models/plugins/mongoMeili';
import messageSchema from '~/schema/message';
/**
* Creates or returns the Message model using the provided mongoose instance and schema
*/
export function createMessageModel(mongoose: typeof import('mongoose')) {
if (process.env.MEILI_HOST && process.env.MEILI_MASTER_KEY) {
messageSchema.plugin(mongoMeili, {
mongoose,
host: process.env.MEILI_HOST,
apiKey: process.env.MEILI_MASTER_KEY,
indexName: 'messages',
primaryKey: 'messageId',
});
}
return mongoose.models.Message || mongoose.model<t.IMessage>('Message', messageSchema);
}

View file

@ -1,6 +1,6 @@
import _ from 'lodash';
import { MeiliSearch, Index } from 'meilisearch';
import mongoose, { Schema, Document, Model, Query } from 'mongoose';
import type { FilterQuery, Types, Schema, Document, Model, Query } from 'mongoose';
import logger from '~/config/meiliLogger';
interface MongoMeiliOptions {
@ -8,6 +8,7 @@ interface MongoMeiliOptions {
apiKey: string;
indexName: string;
primaryKey: string;
mongoose: typeof import('mongoose');
}
interface MeiliIndexable {
@ -314,7 +315,7 @@ const createMeiliMongooseModel = ({
}
await this.collection.updateMany(
{ _id: this._id as mongoose.Types.ObjectId },
{ _id: this._id as Types.ObjectId },
{ $set: { _meiliIndex: true } },
);
}
@ -398,6 +399,7 @@ const createMeiliMongooseModel = ({
* @param options.primaryKey - The primary key field for indexing.
*/
export default function mongoMeili(schema: Schema, options: MongoMeiliOptions): void {
const mongoose = options.mongoose;
validateOptions(options);
// Add _meiliIndex field to the schema to track if a document has been indexed in MeiliSearch.
@ -452,7 +454,7 @@ export default function mongoMeili(schema: Schema, options: MongoMeiliOptions):
const convoIndex = client.index('convos');
const deletedConvos = await mongoose
.model('Conversation')
.find(conditions as mongoose.FilterQuery<unknown>)
.find(conditions as FilterQuery<unknown>)
.lean();
const promises = deletedConvos.map((convo: Record<string, unknown>) =>
convoIndex.deleteDocument(convo.conversationId as string),
@ -464,7 +466,7 @@ export default function mongoMeili(schema: Schema, options: MongoMeiliOptions):
const messageIndex = client.index('messages');
const deletedMessages = await mongoose
.model('Message')
.find(conditions as mongoose.FilterQuery<unknown>)
.find(conditions as FilterQuery<unknown>)
.lean();
const promises = deletedMessages.map((message: Record<string, unknown>) =>
messageIndex.deleteDocument(message.messageId as string),

View file

@ -1,5 +1,4 @@
import { Schema } from 'mongoose';
import mongoMeili from '~/models/plugins/mongoMeili';
import { conversationPreset } from './defaults';
import { IConversation } from '~/types';
@ -48,14 +47,4 @@ convoSchema.index({ expiredAt: 1 }, { expireAfterSeconds: 0 });
convoSchema.index({ createdAt: 1, updatedAt: 1 });
convoSchema.index({ conversationId: 1, user: 1 }, { unique: true });
if (process.env.MEILI_HOST && process.env.MEILI_MASTER_KEY) {
convoSchema.plugin(mongoMeili, {
host: process.env.MEILI_HOST,
apiKey: process.env.MEILI_MASTER_KEY,
/** Note: Will get created automatically if it doesn't exist already */
indexName: 'convos',
primaryKey: 'conversationId',
});
}
export default convoSchema;

View file

@ -1,6 +1,5 @@
import mongoose, { Schema } from 'mongoose';
import type { IMessage } from '~/types/message';
import mongoMeili from '~/models/plugins/mongoMeili';
const messageSchema: Schema<IMessage> = new Schema(
{
@ -166,13 +165,4 @@ messageSchema.index({ expiredAt: 1 }, { expireAfterSeconds: 0 });
messageSchema.index({ createdAt: 1 });
messageSchema.index({ messageId: 1, user: 1 }, { unique: true });
if (process.env.MEILI_HOST && process.env.MEILI_MASTER_KEY) {
messageSchema.plugin(mongoMeili, {
host: process.env.MEILI_HOST,
apiKey: process.env.MEILI_MASTER_KEY,
indexName: 'messages',
primaryKey: 'messageId',
});
}
export default messageSchema;