UNPKG

@dollhousemcp/mcp-server

Version:

DollhouseMCP - A Model Context Protocol (MCP) server that enables dynamic AI persona management from markdown files, allowing Claude and other compatible AI assistants to activate and switch between different behavioral personas.

83 lines 8.2 kB
/** * MetadataIndex - In-memory index of element metadata for fast lookups. * * Primary map: relativePath → ElementIndexEntry * Secondary map: normalizedName → relativePath (case-insensitive name lookup) */ export class MetadataIndex { byPath = new Map(); nameToPath = new Map(); /** * Add or update an entry in the index. * Updates both primary and secondary maps. */ set(entry) { // If this path already existed, clean up old name mapping const existing = this.byPath.get(entry.filePath); if (existing) { const oldNorm = this.normalizeName(existing.name); // Only remove if it still points to this path if (this.nameToPath.get(oldNorm) === entry.filePath) { this.nameToPath.delete(oldNorm); } } this.byPath.set(entry.filePath, entry); this.nameToPath.set(this.normalizeName(entry.name), entry.filePath); } /** * Get an entry by file path. */ get(filePath) { return this.byPath.get(filePath); } /** * Remove an entry by file path. * Cleans up both primary and secondary maps. */ remove(filePath) { const entry = this.byPath.get(filePath); if (entry) { const normName = this.normalizeName(entry.name); // Only remove name mapping if it points to the path being removed if (this.nameToPath.get(normName) === filePath) { this.nameToPath.delete(normName); } this.byPath.delete(filePath); } } /** * O(1) case-insensitive name → path lookup. */ getPathByName(name) { return this.nameToPath.get(this.normalizeName(name)); } /** * Get all index entries. */ getAll() { return [...this.byPath.values()]; } /** * Get all indexed file paths. */ getPaths() { return [...this.byPath.keys()]; } /** * Reset index to empty state. */ clear() { this.byPath.clear(); this.nameToPath.clear(); } /** * Number of indexed entries. */ get size() { return this.byPath.size; } normalizeName(name) { return name.toLowerCase().trim(); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWV0YWRhdGFJbmRleC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdG9yYWdlL01ldGFkYXRhSW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0dBS0c7QUFJSCxNQUFNLE9BQU8sYUFBYTtJQUNoQixNQUFNLEdBQUcsSUFBSSxHQUFHLEVBQTZCLENBQUM7SUFDOUMsVUFBVSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBRS9DOzs7T0FHRztJQUNILEdBQUcsQ0FBQyxLQUF3QjtRQUMxQiwwREFBMEQ7UUFDMUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2pELElBQUksUUFBUSxFQUFFLENBQUM7WUFDYixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNsRCw4Q0FBOEM7WUFDOUMsSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsS0FBSyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ3BELElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ2xDLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVEOztPQUVHO0lBQ0gsR0FBRyxDQUFDLFFBQWdCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU0sQ0FBQyxRQUFnQjtRQUNyQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN4QyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1YsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDaEQsa0VBQWtFO1lBQ2xFLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQy9DLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ25DLENBQUM7WUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYSxDQUFDLElBQVk7UUFDeEIsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTTtRQUNKLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztJQUNuQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxRQUFRO1FBQ04sT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUs7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxJQUFJO1FBQ04sT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztJQUMxQixDQUFDO0lBRU8sYUFBYSxDQUFDLElBQVk7UUFDaEMsT0FBTyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDbkMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBNZXRhZGF0YUluZGV4IC0gSW4tbWVtb3J5IGluZGV4IG9mIGVsZW1lbnQgbWV0YWRhdGEgZm9yIGZhc3QgbG9va3Vwcy5cbiAqXG4gKiBQcmltYXJ5IG1hcDogcmVsYXRpdmVQYXRoIOKGkiBFbGVtZW50SW5kZXhFbnRyeVxuICogU2Vjb25kYXJ5IG1hcDogbm9ybWFsaXplZE5hbWUg4oaSIHJlbGF0aXZlUGF0aCAoY2FzZS1pbnNlbnNpdGl2ZSBuYW1lIGxvb2t1cClcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEVsZW1lbnRJbmRleEVudHJ5IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbmV4cG9ydCBjbGFzcyBNZXRhZGF0YUluZGV4IHtcbiAgcHJpdmF0ZSBieVBhdGggPSBuZXcgTWFwPHN0cmluZywgRWxlbWVudEluZGV4RW50cnk+KCk7XG4gIHByaXZhdGUgbmFtZVRvUGF0aCA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG5cbiAgLyoqXG4gICAqIEFkZCBvciB1cGRhdGUgYW4gZW50cnkgaW4gdGhlIGluZGV4LlxuICAgKiBVcGRhdGVzIGJvdGggcHJpbWFyeSBhbmQgc2Vjb25kYXJ5IG1hcHMuXG4gICAqL1xuICBzZXQoZW50cnk6IEVsZW1lbnRJbmRleEVudHJ5KTogdm9pZCB7XG4gICAgLy8gSWYgdGhpcyBwYXRoIGFscmVhZHkgZXhpc3RlZCwgY2xlYW4gdXAgb2xkIG5hbWUgbWFwcGluZ1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5ieVBhdGguZ2V0KGVudHJ5LmZpbGVQYXRoKTtcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIGNvbnN0IG9sZE5vcm0gPSB0aGlzLm5vcm1hbGl6ZU5hbWUoZXhpc3RpbmcubmFtZSk7XG4gICAgICAvLyBPbmx5IHJlbW92ZSBpZiBpdCBzdGlsbCBwb2ludHMgdG8gdGhpcyBwYXRoXG4gICAgICBpZiAodGhpcy5uYW1lVG9QYXRoLmdldChvbGROb3JtKSA9PT0gZW50cnkuZmlsZVBhdGgpIHtcbiAgICAgICAgdGhpcy5uYW1lVG9QYXRoLmRlbGV0ZShvbGROb3JtKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLmJ5UGF0aC5zZXQoZW50cnkuZmlsZVBhdGgsIGVudHJ5KTtcbiAgICB0aGlzLm5hbWVUb1BhdGguc2V0KHRoaXMubm9ybWFsaXplTmFtZShlbnRyeS5uYW1lKSwgZW50cnkuZmlsZVBhdGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbiBlbnRyeSBieSBmaWxlIHBhdGguXG4gICAqL1xuICBnZXQoZmlsZVBhdGg6IHN0cmluZyk6IEVsZW1lbnRJbmRleEVudHJ5IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5ieVBhdGguZ2V0KGZpbGVQYXRoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgYW4gZW50cnkgYnkgZmlsZSBwYXRoLlxuICAgKiBDbGVhbnMgdXAgYm90aCBwcmltYXJ5IGFuZCBzZWNvbmRhcnkgbWFwcy5cbiAgICovXG4gIHJlbW92ZShmaWxlUGF0aDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgZW50cnkgPSB0aGlzLmJ5UGF0aC5nZXQoZmlsZVBhdGgpO1xuICAgIGlmIChlbnRyeSkge1xuICAgICAgY29uc3Qgbm9ybU5hbWUgPSB0aGlzLm5vcm1hbGl6ZU5hbWUoZW50cnkubmFtZSk7XG4gICAgICAvLyBPbmx5IHJlbW92ZSBuYW1lIG1hcHBpbmcgaWYgaXQgcG9pbnRzIHRvIHRoZSBwYXRoIGJlaW5nIHJlbW92ZWRcbiAgICAgIGlmICh0aGlzLm5hbWVUb1BhdGguZ2V0KG5vcm1OYW1lKSA9PT0gZmlsZVBhdGgpIHtcbiAgICAgICAgdGhpcy5uYW1lVG9QYXRoLmRlbGV0ZShub3JtTmFtZSk7XG4gICAgICB9XG4gICAgICB0aGlzLmJ5UGF0aC5kZWxldGUoZmlsZVBhdGgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBPKDEpIGNhc2UtaW5zZW5zaXRpdmUgbmFtZSDihpIgcGF0aCBsb29rdXAuXG4gICAqL1xuICBnZXRQYXRoQnlOYW1lKG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMubmFtZVRvUGF0aC5nZXQodGhpcy5ub3JtYWxpemVOYW1lKG5hbWUpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYWxsIGluZGV4IGVudHJpZXMuXG4gICAqL1xuICBnZXRBbGwoKTogRWxlbWVudEluZGV4RW50cnlbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLmJ5UGF0aC52YWx1ZXMoKV07XG4gIH1cblxuICAvKipcbiAgICogR2V0IGFsbCBpbmRleGVkIGZpbGUgcGF0aHMuXG4gICAqL1xuICBnZXRQYXRocygpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIFsuLi50aGlzLmJ5UGF0aC5rZXlzKCldO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc2V0IGluZGV4IHRvIGVtcHR5IHN0YXRlLlxuICAgKi9cbiAgY2xlYXIoKTogdm9pZCB7XG4gICAgdGhpcy5ieVBhdGguY2xlYXIoKTtcbiAgICB0aGlzLm5hbWVUb1BhdGguY2xlYXIoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgaW5kZXhlZCBlbnRyaWVzLlxuICAgKi9cbiAgZ2V0IHNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5ieVBhdGguc2l6ZTtcbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXplTmFtZShuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBuYW1lLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xuICB9XG59XG4iXX0=