feat(search): load/save persisted guild search index + searchIndexMeta (v0.8.87)
Integrate GuildSearchIndexStore on platform startup and debounced persist after message ingest. Expose getGuildSearchIndexMeta and view.searchIndexMeta for smokes and UI diagnostics. Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -150,6 +150,8 @@ const {
|
|||||||
const { forumPostHaystack } = require('pearcord-forum-search')
|
const { forumPostHaystack } = require('pearcord-forum-search')
|
||||||
const {
|
const {
|
||||||
GuildSearchIndex,
|
GuildSearchIndex,
|
||||||
|
GuildSearchIndexStore,
|
||||||
|
indexFromSerialized,
|
||||||
buildIndexRow,
|
buildIndexRow,
|
||||||
mergeSearchHits,
|
mergeSearchHits,
|
||||||
compactMeshSearchHit,
|
compactMeshSearchHit,
|
||||||
@@ -311,6 +313,8 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
this._searchIncludeMesh = true
|
this._searchIncludeMesh = true
|
||||||
this._lastSearchMeshMeta = null
|
this._lastSearchMeshMeta = null
|
||||||
this._guildSearchIndexes = new Map()
|
this._guildSearchIndexes = new Map()
|
||||||
|
this._searchIndexStore = null
|
||||||
|
this._searchIndexPersistTimers = new Map()
|
||||||
this._searchMeshWaiters = new Map()
|
this._searchMeshWaiters = new Map()
|
||||||
this._threadsPanelFilter = 'active'
|
this._threadsPanelFilter = 'active'
|
||||||
this._readOnly = opts.readOnly === true
|
this._readOnly = opts.readOnly === true
|
||||||
@@ -1105,11 +1109,37 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
return hits.sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0)).slice(0, limit)
|
return hits.sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0)).slice(0, limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_getSearchIndexStore () {
|
||||||
|
if (!this._searchIndexStore) {
|
||||||
|
this._searchIndexStore = new GuildSearchIndexStore(this.storagePath)
|
||||||
|
}
|
||||||
|
return this._searchIndexStore
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduleSearchIndexPersist (guildId) {
|
||||||
|
if (!guildId) return
|
||||||
|
const prev = this._searchIndexPersistTimers.get(guildId)
|
||||||
|
if (prev) clearTimeout(prev)
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
this._searchIndexPersistTimers.delete(guildId)
|
||||||
|
const idx = this._guildSearchIndexes.get(guildId)
|
||||||
|
if (idx) this._getSearchIndexStore().save(guildId, idx)
|
||||||
|
}, 400)
|
||||||
|
this._searchIndexPersistTimers.set(guildId, timer)
|
||||||
|
}
|
||||||
|
|
||||||
async _ensureGuildSearchIndex (guildId) {
|
async _ensureGuildSearchIndex (guildId) {
|
||||||
let idx = this._guildSearchIndexes.get(guildId)
|
let idx = this._guildSearchIndexes.get(guildId)
|
||||||
if (idx) return idx
|
if (idx) return idx
|
||||||
|
const blob = this._getSearchIndexStore().load(guildId)
|
||||||
|
if (blob?.rows?.length) {
|
||||||
|
idx = indexFromSerialized(blob)
|
||||||
|
this._guildSearchIndexes.set(guildId, idx)
|
||||||
|
return idx
|
||||||
|
}
|
||||||
idx = await this.rebuildGuildSearchIndex(guildId)
|
idx = await this.rebuildGuildSearchIndex(guildId)
|
||||||
this._guildSearchIndexes.set(guildId, idx)
|
this._guildSearchIndexes.set(guildId, idx)
|
||||||
|
this._getSearchIndexStore().save(guildId, idx)
|
||||||
return idx
|
return idx
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1143,14 +1173,15 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
this._getSearchIndexStore().save(guildId, idx)
|
||||||
return idx
|
return idx
|
||||||
}
|
}
|
||||||
|
|
||||||
_indexMessageForSearch (message, channel) {
|
async _indexMessageForSearch (message, channel) {
|
||||||
if (!message?.id || !this.guild?.guild?.id) return
|
if (!message?.id || !this.guild?.guild?.id) return
|
||||||
const guildId = this.guild.guild.id
|
const guildId = this.guild.guild.id
|
||||||
let idx = this._guildSearchIndexes.get(guildId)
|
let idx = this._guildSearchIndexes.get(guildId)
|
||||||
if (!idx) return
|
if (!idx) idx = await this._ensureGuildSearchIndex(guildId)
|
||||||
const enriched = enrichMessageRow(message)
|
const enriched = enrichMessageRow(message)
|
||||||
idx.upsert(
|
idx.upsert(
|
||||||
buildIndexRow(enriched, channel, {
|
buildIndexRow(enriched, channel, {
|
||||||
@@ -1159,6 +1190,7 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
stickerNames: enriched.stickerNames
|
stickerNames: enriched.stickerNames
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
this._scheduleSearchIndexPersist(guildId)
|
||||||
}
|
}
|
||||||
|
|
||||||
async searchGuildMessages (guildId, query, opts = {}) {
|
async searchGuildMessages (guildId, query, opts = {}) {
|
||||||
@@ -1212,6 +1244,18 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getGuildSearchIndexMeta (guildId) {
|
||||||
|
const id = guildId || this.guild?.guild?.id
|
||||||
|
if (!id) return { persisted: false, rowCount: 0, savedAt: null }
|
||||||
|
const blob = this._getSearchIndexStore().load(id)
|
||||||
|
const mem = this._guildSearchIndexes.get(id)
|
||||||
|
return {
|
||||||
|
persisted: !!(blob?.rows?.length),
|
||||||
|
savedAt: blob?.savedAt || null,
|
||||||
|
rowCount: blob?.rows?.length || mem?._rows?.length || 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async searchGuildMessagesWithMesh (guildId, query, opts = {}) {
|
async searchGuildMessagesWithMesh (guildId, query, opts = {}) {
|
||||||
const local = await this.searchGuildMessages(guildId, query, opts)
|
const local = await this.searchGuildMessages(guildId, query, opts)
|
||||||
if (opts.mesh === false || !this.guild?.guild) {
|
if (opts.mesh === false || !this.guild?.guild) {
|
||||||
@@ -8641,6 +8685,9 @@ class PearcordPlatform extends EventEmitter {
|
|||||||
forumIncludeArchived: this._forumIncludeArchived,
|
forumIncludeArchived: this._forumIncludeArchived,
|
||||||
searchResults: await this._resolveSearchResults(),
|
searchResults: await this._resolveSearchResults(),
|
||||||
searchMeshMeta: this._lastSearchMeshMeta,
|
searchMeshMeta: this._lastSearchMeshMeta,
|
||||||
|
searchIndexMeta: this.guild?.guild
|
||||||
|
? this.getGuildSearchIndexMeta(this.guild.guild.id)
|
||||||
|
: { persisted: false, rowCount: 0, savedAt: null },
|
||||||
searchIncludeMesh: this._searchIncludeMesh,
|
searchIncludeMesh: this._searchIncludeMesh,
|
||||||
companionMode: this._companionMode,
|
companionMode: this._companionMode,
|
||||||
readOnly: this._readOnly,
|
readOnly: this._readOnly,
|
||||||
|
|||||||
Reference in New Issue
Block a user