{"version":3,"file":"index4.cjs","sources":["../src/runtime/context.ts"],"sourcesContent":["/**\n * Context Runtime\n * \n * Main entry point for the context runtime system. Provides a factory function\n * to create context instances that can discover, load, and manage\n * entity data from hierarchical configuration directories.\n */\n\nimport { \n    RedaksjonEntity,\n    Person, \n    Project, \n    Company, \n    Term,\n    IgnoredTerm,\n} from '../types';\nimport * as OvercontextAdapter from '../storage/adapter';\nimport { getProjectRelationshipDistance } from '../helpers';\nimport type {\n    ContextDiscoveryOptions,\n    DiscoveredContextDir,\n    HierarchicalContextResult,\n} from '../discovery/types';\nimport { loadHierarchicalConfig } from '../discovery/overcontext-discovery';\n\nexport interface ContextInstance {\n    // Initialization\n    load(): Promise<void>;\n    reload(): Promise<void>;\n  \n    // Discovery info\n    getDiscoveredDirs(): DiscoveredContextDir[];\n    getConfig(): Record<string, unknown>;\n    getContextDirs(): string[];\n  \n    // Entity access\n    getPerson(id: string): Person | undefined;\n    getProject(id: string): Project | undefined;\n    getCompany(id: string): Company | undefined;\n    getTerm(id: string): Term | undefined;\n    getIgnored(id: string): IgnoredTerm | undefined;\n  \n    getAllPeople(): Person[];\n    getAllProjects(): Project[];\n    getAllCompanies(): Company[];\n    getAllTerms(): Term[];\n    getAllIgnored(): IgnoredTerm[];\n  \n    // Check if a term is ignored\n    isIgnored(term: string): boolean;\n  \n    // Search\n    search(query: string): RedaksjonEntity[];\n    findBySoundsLike(phonetic: string): RedaksjonEntity | undefined;\n  \n    // Advanced search with context awareness\n    searchWithContext(query: string, contextProjectId?: string): RedaksjonEntity[];\n    getRelatedProjects(projectId: string, maxDistance?: number): Project[];\n  \n    // Modification\n    saveEntity(entity: RedaksjonEntity, allowUpdate?: boolean): Promise<void>;\n    deleteEntity(entity: RedaksjonEntity): Promise<boolean>;\n    getEntityFilePath(entity: RedaksjonEntity): string | undefined;\n  \n    // Check if context is available\n    hasContext(): boolean;\n}\n\nexport interface CreateOptions {\n    startingDir?: string;\n    configDirName?: string;\n    configFileName?: string;\n    /** Explicit context directories to load entities from (bypasses discovery) */\n    contextDirectories?: string[];\n    /** Optional GCS-backed context storage configuration */\n    gcs?: {\n        bucketName: string;\n        basePath: string;\n        projectId?: string;\n        credentialsFile?: string;\n    };\n}\n\n/**\n * Create a new context instance using overcontext\n */\nexport const create = async (options: CreateOptions = {}): Promise<ContextInstance> => {\n    const discoveryOptions: ContextDiscoveryOptions = {\n        configDirName: options.configDirName ?? '.protokoll',\n        configFileName: options.configFileName ?? 'config.yaml',\n        startingDir: options.startingDir,\n    };\n\n    const storage = OvercontextAdapter.create({ gcs: options.gcs });\n    let discoveryResult: HierarchicalContextResult = {\n        config: {},\n        discoveredDirs: [],\n        contextDirs: [],\n    };\n\n    const loadContext = async (): Promise<void> => {\n        // GCS mode does not use filesystem discovery.\n        if (options.gcs) {\n            discoveryResult = {\n                config: {},\n                discoveredDirs: [{\n                    path: `gs://${options.gcs.bucketName}/${options.gcs.basePath}`,\n                    level: 0,\n                }],\n                contextDirs: [options.gcs.basePath],\n            };\n        } else if (options.contextDirectories && options.contextDirectories.length > 0) {\n            // If explicit contextDirectories are provided, use them directly\n            discoveryResult = {\n                config: {},\n                discoveredDirs: options.contextDirectories.map((dir, index) => ({\n                    path: dir,\n                    level: index,\n                })),\n                contextDirs: options.contextDirectories,\n            };\n        } else {\n            // Otherwise, use configuration directory discovery\n            discoveryResult = await loadHierarchicalConfig(discoveryOptions);\n        }\n        storage.clear();\n        await storage.load(discoveryResult.contextDirs);\n    };\n\n    // Initial load\n    await loadContext();\n\n    return {\n        load: loadContext,\n    \n        reload: async () => {\n            storage.clear();\n            await storage.load(discoveryResult.contextDirs);\n        },\n    \n        getDiscoveredDirs: () => discoveryResult.discoveredDirs,\n        getConfig: () => discoveryResult.config,\n        getContextDirs: () => discoveryResult.contextDirs,\n    \n        getPerson: (id) => storage.get<Person>('person', id),\n        getProject: (id) => storage.get<Project>('project', id),\n        getCompany: (id) => storage.get<Company>('company', id),\n        getTerm: (id) => storage.get<Term>('term', id),\n        getIgnored: (id) => storage.get<IgnoredTerm>('ignored', id),\n    \n        getAllPeople: () => storage.getAll<Person>('person'),\n        getAllProjects: () => storage.getAll<Project>('project'),\n        getAllCompanies: () => storage.getAll<Company>('company'),\n        getAllTerms: () => storage.getAll<Term>('term'),\n        getAllIgnored: () => storage.getAll<IgnoredTerm>('ignored'),\n        \n        isIgnored: (term: string) => {\n            const normalizedTerm = term.toLowerCase().replace(/[^a-z0-9]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');\n            const ignoredTerms = storage.getAll<IgnoredTerm>('ignored');\n            return ignoredTerms.some(ignored => \n                ignored.id === normalizedTerm || \n                ignored.name.toLowerCase() === term.toLowerCase()\n            );\n        },\n    \n        search: (query) => storage.search(query),\n        findBySoundsLike: (phonetic) => storage.findBySoundsLike(phonetic),\n        \n        searchWithContext: (query, contextProjectId) => {\n            const results = storage.search(query);\n            \n            if (!contextProjectId) {\n                return results;\n            }\n            \n            const contextProject = storage.get<Project>('project', contextProjectId);\n            if (!contextProject) {\n                return results;\n            }\n            \n            const scoredResults = results.map(entity => {\n                let score = 0;\n                \n                if (entity.type === 'project') {\n                    const distance = getProjectRelationshipDistance(contextProject, entity as Project);\n                    if (distance >= 0) {\n                        score += (3 - distance) * 50;\n                    }\n                }\n                \n                if (entity.type === 'term') {\n                    const term = entity as Term;\n                    if (term.projects?.includes(contextProjectId)) {\n                        score += 100;\n                    }\n                }\n                \n                return { entity, score };\n            });\n            \n            return scoredResults\n                .sort((a, b) => b.score - a.score)\n                .map(r => r.entity);\n        },\n        \n        getRelatedProjects: (projectId, maxDistance = 2) => {\n            const project = storage.get<Project>('project', projectId);\n            if (!project) return [];\n            \n            const allProjects = storage.getAll<Project>('project');\n            const related: Array<{ project: Project; distance: number }> = [];\n            \n            for (const otherProject of allProjects) {\n                if (otherProject.id === projectId) continue;\n                \n                const distance = getProjectRelationshipDistance(project, otherProject);\n                if (distance >= 0 && distance <= maxDistance) {\n                    related.push({ project: otherProject, distance });\n                }\n            }\n            \n            return related\n                .sort((a, b) => a.distance - b.distance)\n                .map(r => r.project);\n        },\n    \n        saveEntity: async (entity, allowUpdate = false) => {\n            const closestDir = discoveryResult.discoveredDirs\n                .sort((a, b) => a.level - b.level)[0];\n      \n            if (!closestDir) {\n                throw new Error('No configuration directory found. Cannot save entity.');\n            }\n      \n            await storage.save(entity, closestDir.path, allowUpdate);\n        },\n        \n        deleteEntity: async (entity) => {\n            const filePath = storage.getEntityFilePath(entity.type, entity.id, discoveryResult.contextDirs);\n            if (!filePath) {\n                return false;\n            }\n            \n            const contextDir = discoveryResult.contextDirs.find(dir => filePath.startsWith(dir));\n            if (!contextDir) {\n                return false;\n            }\n            \n            return storage.delete(entity.type, entity.id, contextDir);\n        },\n        \n        getEntityFilePath: (entity) => {\n            return storage.getEntityFilePath(entity.type, entity.id, discoveryResult.contextDirs);\n        },\n    \n        hasContext: () => discoveryResult.discoveredDirs.length > 0,\n    };\n};\n"],"names":["OvercontextAdapter.create","loadHierarchicalConfig","getProjectRelationshipDistance"],"mappings":";;;;;;;;AAsFO,MAAM,MAAA,GAAS,OAAO,OAAA,GAAyB,EAAC,KAAgC;AACnF,EAAA,MAAM,gBAAA,GAA4C;AAAA,IAC9C,aAAA,EAAe,QAAQ,aAAA,IAAiB,YAAA;AAAA,IACxC,cAAA,EAAgB,QAAQ,cAAA,IAAkB,aAAA;AAAA,IAC1C,aAAa,OAAA,CAAQ;AAAA,GACzB;AAEA,EAAA,MAAM,UAAUA,cAAmB,CAAO,EAAE,GAAA,EAAK,OAAA,CAAQ,KAAK,CAAA;AAC9D,EAAA,IAAI,eAAA,GAA6C;AAAA,IAC7C,QAAQ,EAAC;AAAA,IACT,gBAAgB,EAAC;AAAA,IACjB,aAAa;AAAC,GAClB;AAEA,EAAA,MAAM,cAAc,YAA2B;AAE3C,IAAA,IAAI,QAAQ,GAAA,EAAK;AACb,MAAA,eAAA,GAAkB;AAAA,QACd,QAAQ,EAAC;AAAA,QACT,gBAAgB,CAAC;AAAA,UACb,IAAA,EAAM,QAAQ,OAAA,CAAQ,GAAA,CAAI,UAAU,CAAA,CAAA,EAAI,OAAA,CAAQ,IAAI,QAAQ,CAAA,CAAA;AAAA,UAC5D,KAAA,EAAO;AAAA,SACV,CAAA;AAAA,QACD,WAAA,EAAa,CAAC,OAAA,CAAQ,GAAA,CAAI,QAAQ;AAAA,OACtC;AAAA,IACJ,WAAW,OAAA,CAAQ,kBAAA,IAAsB,OAAA,CAAQ,kBAAA,CAAmB,SAAS,CAAA,EAAG;AAE5E,MAAA,eAAA,GAAkB;AAAA,QACd,QAAQ,EAAC;AAAA,QACT,gBAAgB,OAAA,CAAQ,kBAAA,CAAmB,GAAA,CAAI,CAAC,KAAK,KAAA,MAAW;AAAA,UAC5D,IAAA,EAAM,GAAA;AAAA,UACN,KAAA,EAAO;AAAA,SACX,CAAE,CAAA;AAAA,QACF,aAAa,OAAA,CAAQ;AAAA,OACzB;AAAA,IACJ,CAAA,MAAO;AAEH,MAAA,eAAA,GAAkB,MAAMC,4CAAuB,gBAAgB,CAAA;AAAA,IACnE;AACA,IAAA,OAAA,CAAQ,KAAA,EAAM;AACd,IAAA,MAAM,OAAA,CAAQ,IAAA,CAAK,eAAA,CAAgB,WAAW,CAAA;AAAA,EAClD,CAAA;AAGA,EAAA,MAAM,WAAA,EAAY;AAElB,EAAA,OAAO;AAAA,IACH,IAAA,EAAM,WAAA;AAAA,IAEN,QAAQ,YAAY;AAChB,MAAA,OAAA,CAAQ,KAAA,EAAM;AACd,MAAA,MAAM,OAAA,CAAQ,IAAA,CAAK,eAAA,CAAgB,WAAW,CAAA;AAAA,IAClD,CAAA;AAAA,IAEA,iBAAA,EAAmB,MAAM,eAAA,CAAgB,cAAA;AAAA,IACzC,SAAA,EAAW,MAAM,eAAA,CAAgB,MAAA;AAAA,IACjC,cAAA,EAAgB,MAAM,eAAA,CAAgB,WAAA;AAAA,IAEtC,WAAW,CAAC,EAAA,KAAO,OAAA,CAAQ,GAAA,CAAY,UAAU,EAAE,CAAA;AAAA,IACnD,YAAY,CAAC,EAAA,KAAO,OAAA,CAAQ,GAAA,CAAa,WAAW,EAAE,CAAA;AAAA,IACtD,YAAY,CAAC,EAAA,KAAO,OAAA,CAAQ,GAAA,CAAa,WAAW,EAAE,CAAA;AAAA,IACtD,SAAS,CAAC,EAAA,KAAO,OAAA,CAAQ,GAAA,CAAU,QAAQ,EAAE,CAAA;AAAA,IAC7C,YAAY,CAAC,EAAA,KAAO,OAAA,CAAQ,GAAA,CAAiB,WAAW,EAAE,CAAA;AAAA,IAE1D,YAAA,EAAc,MAAM,OAAA,CAAQ,MAAA,CAAe,QAAQ,CAAA;AAAA,IACnD,cAAA,EAAgB,MAAM,OAAA,CAAQ,MAAA,CAAgB,SAAS,CAAA;AAAA,IACvD,eAAA,EAAiB,MAAM,OAAA,CAAQ,MAAA,CAAgB,SAAS,CAAA;AAAA,IACxD,WAAA,EAAa,MAAM,OAAA,CAAQ,MAAA,CAAa,MAAM,CAAA;AAAA,IAC9C,aAAA,EAAe,MAAM,OAAA,CAAQ,MAAA,CAAoB,SAAS,CAAA;AAAA,IAE1D,SAAA,EAAW,CAAC,IAAA,KAAiB;AACzB,MAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,WAAA,EAAY,CAAE,QAAQ,YAAA,EAAc,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,UAAU,EAAE,CAAA;AAC7G,MAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,MAAA,CAAoB,SAAS,CAAA;AAC1D,MAAA,OAAO,YAAA,CAAa,IAAA;AAAA,QAAK,CAAA,OAAA,KACrB,QAAQ,EAAA,KAAO,cAAA,IACf,QAAQ,IAAA,CAAK,WAAA,EAAY,KAAM,IAAA,CAAK,WAAA;AAAY,OACpD;AAAA,IACJ,CAAA;AAAA,IAEA,MAAA,EAAQ,CAAC,KAAA,KAAU,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA,IACvC,gBAAA,EAAkB,CAAC,QAAA,KAAa,OAAA,CAAQ,iBAAiB,QAAQ,CAAA;AAAA,IAEjE,iBAAA,EAAmB,CAAC,KAAA,EAAO,gBAAA,KAAqB;AAC5C,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,KAAK,CAAA;AAEpC,MAAA,IAAI,CAAC,gBAAA,EAAkB;AACnB,QAAA,OAAO,OAAA;AAAA,MACX;AAEA,MAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,GAAA,CAAa,SAAA,EAAW,gBAAgB,CAAA;AACvE,MAAA,IAAI,CAAC,cAAA,EAAgB;AACjB,QAAA,OAAO,OAAA;AAAA,MACX;AAEA,MAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,GAAA,CAAI,CAAA,MAAA,KAAU;AACxC,QAAA,IAAI,KAAA,GAAQ,CAAA;AAEZ,QAAA,IAAI,MAAA,CAAO,SAAS,SAAA,EAAW;AAC3B,UAAA,MAAM,QAAA,GAAWC,sCAAA,CAA+B,cAAA,EAAgB,MAAiB,CAAA;AACjF,UAAA,IAAI,YAAY,CAAA,EAAG;AACf,YAAA,KAAA,IAAA,CAAU,IAAI,QAAA,IAAY,EAAA;AAAA,UAC9B;AAAA,QACJ;AAEA,QAAA,IAAI,MAAA,CAAO,SAAS,MAAA,EAAQ;AACxB,UAAA,MAAM,IAAA,GAAO,MAAA;AACb,UAAA,IAAI,IAAA,CAAK,QAAA,EAAU,QAAA,CAAS,gBAAgB,CAAA,EAAG;AAC3C,YAAA,KAAA,IAAS,GAAA;AAAA,UACb;AAAA,QACJ;AAEA,QAAA,OAAO,EAAE,QAAQ,KAAA,EAAM;AAAA,MAC3B,CAAC,CAAA;AAED,MAAA,OAAO,aAAA,CACF,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,KAAK,CAAA,CAChC,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,MAAM,CAAA;AAAA,IAC1B,CAAA;AAAA,IAEA,kBAAA,EAAoB,CAAC,SAAA,EAAW,WAAA,GAAc,CAAA,KAAM;AAChD,MAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,GAAA,CAAa,SAAA,EAAW,SAAS,CAAA;AACzD,MAAA,IAAI,CAAC,OAAA,EAAS,OAAO,EAAC;AAEtB,MAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,MAAA,CAAgB,SAAS,CAAA;AACrD,MAAA,MAAM,UAAyD,EAAC;AAEhE,MAAA,KAAA,MAAW,gBAAgB,WAAA,EAAa;AACpC,QAAA,IAAI,YAAA,CAAa,OAAO,SAAA,EAAW;AAEnC,QAAA,MAAM,QAAA,GAAWA,sCAAA,CAA+B,OAAA,EAAS,YAAY,CAAA;AACrE,QAAA,IAAI,QAAA,IAAY,CAAA,IAAK,QAAA,IAAY,WAAA,EAAa;AAC1C,UAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,OAAA,EAAS,YAAA,EAAc,UAAU,CAAA;AAAA,QACpD;AAAA,MACJ;AAEA,MAAA,OAAO,OAAA,CACF,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE,QAAQ,CAAA,CACtC,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,OAAO,CAAA;AAAA,IAC3B,CAAA;AAAA,IAEA,UAAA,EAAY,OAAO,MAAA,EAAQ,WAAA,GAAc,KAAA,KAAU;AAC/C,MAAA,MAAM,UAAA,GAAa,eAAA,CAAgB,cAAA,CAC9B,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,KAAK,CAAA,CAAE,CAAC,CAAA;AAExC,MAAA,IAAI,CAAC,UAAA,EAAY;AACb,QAAA,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAAA,MAC3E;AAEA,MAAA,MAAM,OAAA,CAAQ,IAAA,CAAK,MAAA,EAAQ,UAAA,CAAW,MAAM,WAAW,CAAA;AAAA,IAC3D,CAAA;AAAA,IAEA,YAAA,EAAc,OAAO,MAAA,KAAW;AAC5B,MAAA,MAAM,QAAA,GAAW,QAAQ,iBAAA,CAAkB,MAAA,CAAO,MAAM,MAAA,CAAO,EAAA,EAAI,gBAAgB,WAAW,CAAA;AAC9F,MAAA,IAAI,CAAC,QAAA,EAAU;AACX,QAAA,OAAO,KAAA;AAAA,MACX;AAEA,MAAA,MAAM,UAAA,GAAa,gBAAgB,WAAA,CAAY,IAAA,CAAK,SAAO,QAAA,CAAS,UAAA,CAAW,GAAG,CAAC,CAAA;AACnF,MAAA,IAAI,CAAC,UAAA,EAAY;AACb,QAAA,OAAO,KAAA;AAAA,MACX;AAEA,MAAA,OAAO,QAAQ,MAAA,CAAO,MAAA,CAAO,IAAA,EAAM,MAAA,CAAO,IAAI,UAAU,CAAA;AAAA,IAC5D,CAAA;AAAA,IAEA,iBAAA,EAAmB,CAAC,MAAA,KAAW;AAC3B,MAAA,OAAO,QAAQ,iBAAA,CAAkB,MAAA,CAAO,MAAM,MAAA,CAAO,EAAA,EAAI,gBAAgB,WAAW,CAAA;AAAA,IACxF,CAAA;AAAA,IAEA,UAAA,EAAY,MAAM,eAAA,CAAgB,cAAA,CAAe,MAAA,GAAS;AAAA,GAC9D;AACJ;;;;"}