@redaksjon/context 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index4.cjs CHANGED
@@ -12,14 +12,23 @@ const create = async (options = {}) => {
12
12
  configFileName: options.configFileName ?? "config.yaml",
13
13
  startingDir: options.startingDir
14
14
  };
15
- const storage = adapter.create();
15
+ const storage = adapter.create({ gcs: options.gcs });
16
16
  let discoveryResult = {
17
17
  config: {},
18
18
  discoveredDirs: [],
19
19
  contextDirs: []
20
20
  };
21
21
  const loadContext = async () => {
22
- if (options.contextDirectories && options.contextDirectories.length > 0) {
22
+ if (options.gcs) {
23
+ discoveryResult = {
24
+ config: {},
25
+ discoveredDirs: [{
26
+ path: `gs://${options.gcs.bucketName}/${options.gcs.basePath}`,
27
+ level: 0
28
+ }],
29
+ contextDirs: [options.gcs.basePath]
30
+ };
31
+ } else if (options.contextDirectories && options.contextDirectories.length > 0) {
23
32
  discoveryResult = {
24
33
  config: {},
25
34
  discoveredDirs: options.contextDirectories.map((dir, index) => ({
@@ -1 +1 @@
1
- {"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}\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();\n let discoveryResult: HierarchicalContextResult = {\n config: {},\n discoveredDirs: [],\n contextDirs: [],\n };\n\n const loadContext = async (): Promise<void> => {\n // If explicit contextDirectories are provided, use them directly\n if (options.contextDirectories && options.contextDirectories.length > 0) {\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":"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"}
1
+ {"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 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":"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"}
package/dist/index4.js CHANGED
@@ -8,14 +8,23 @@ const create = async (options = {}) => {
8
8
  configFileName: options.configFileName ?? "config.yaml",
9
9
  startingDir: options.startingDir
10
10
  };
11
- const storage = create$1();
11
+ const storage = create$1({ gcs: options.gcs });
12
12
  let discoveryResult = {
13
13
  config: {},
14
14
  discoveredDirs: [],
15
15
  contextDirs: []
16
16
  };
17
17
  const loadContext = async () => {
18
- if (options.contextDirectories && options.contextDirectories.length > 0) {
18
+ if (options.gcs) {
19
+ discoveryResult = {
20
+ config: {},
21
+ discoveredDirs: [{
22
+ path: `gs://${options.gcs.bucketName}/${options.gcs.basePath}`,
23
+ level: 0
24
+ }],
25
+ contextDirs: [options.gcs.basePath]
26
+ };
27
+ } else if (options.contextDirectories && options.contextDirectories.length > 0) {
19
28
  discoveryResult = {
20
29
  config: {},
21
30
  discoveredDirs: options.contextDirectories.map((dir, index) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"index4.js","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}\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();\n let discoveryResult: HierarchicalContextResult = {\n config: {},\n discoveredDirs: [],\n contextDirs: [],\n };\n\n const loadContext = async (): Promise<void> => {\n // If explicit contextDirectories are provided, use them directly\n if (options.contextDirectories && options.contextDirectories.length > 0) {\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"],"mappings":"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"}
1
+ {"version":3,"file":"index4.js","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 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"],"mappings":"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"}
package/dist/index5.cjs CHANGED
@@ -41,7 +41,7 @@ const TYPE_TO_DIRECTORY = {
41
41
  term: "terms",
42
42
  ignored: "ignored"
43
43
  };
44
- const create = () => {
44
+ const create = (options = {}) => {
45
45
  const cache = /* @__PURE__ */ new Map();
46
46
  let api;
47
47
  let loadedContextDirs = [];
@@ -62,16 +62,40 @@ const create = () => {
62
62
  return;
63
63
  }
64
64
  try {
65
- const lastContextDir = contextDirs[contextDirs.length - 1];
66
- const startDir = path__namespace.dirname(lastContextDir);
67
- api = await overcontext.discoverOvercontext({
68
- schemas: index.redaksjonSchemas,
69
- pluralNames: index.redaksjonPluralNames,
70
- startDir,
71
- contextDirName: path__namespace.basename(lastContextDir),
72
- maxLevels: 1,
73
- filenameStrategy: redaksjonFilenameStrategy
74
- });
65
+ if (options.gcs) {
66
+ const registry = overcontext.createSchemaRegistry();
67
+ for (const [type, schema] of Object.entries(index.redaksjonSchemas)) {
68
+ registry.register({
69
+ type,
70
+ schema,
71
+ pluralName: index.redaksjonPluralNames[type] ?? `${type}s`
72
+ });
73
+ }
74
+ if (options.gcs.credentialsFile && !process.env.GOOGLE_APPLICATION_CREDENTIALS) {
75
+ process.env.GOOGLE_APPLICATION_CREDENTIALS = options.gcs.credentialsFile;
76
+ }
77
+ const provider = await overcontext.createFjellGcsProvider({
78
+ bucketName: options.gcs.bucketName,
79
+ basePath: options.gcs.basePath,
80
+ registry
81
+ });
82
+ api = overcontext.createContext({
83
+ provider,
84
+ registry,
85
+ schemas: index.redaksjonSchemas
86
+ });
87
+ } else {
88
+ const lastContextDir = contextDirs[contextDirs.length - 1];
89
+ const startDir = path__namespace.dirname(lastContextDir);
90
+ api = await overcontext.discoverOvercontext({
91
+ schemas: index.redaksjonSchemas,
92
+ pluralNames: index.redaksjonPluralNames,
93
+ startDir,
94
+ contextDirName: path__namespace.basename(lastContextDir),
95
+ maxLevels: 1,
96
+ filenameStrategy: redaksjonFilenameStrategy
97
+ });
98
+ }
75
99
  for (const type of ["person", "project", "company", "term", "ignored"]) {
76
100
  const entities = await api.getAll(type);
77
101
  for (const entity of entities) {
@@ -150,6 +174,9 @@ const create = () => {
150
174
  api = void 0;
151
175
  },
152
176
  getEntityFilePath(type, id, contextDirs) {
177
+ if (options.gcs) {
178
+ return void 0;
179
+ }
153
180
  const dirName = TYPE_TO_DIRECTORY[type];
154
181
  const dirsToSearch = contextDirs.length > 0 ? contextDirs : loadedContextDirs;
155
182
  const entity = cache.get(type)?.get(id);
@@ -1 +1 @@
1
- {"version":3,"file":"index5.cjs","sources":["../src/storage/adapter.ts"],"sourcesContent":["import { \n discoverOvercontext, \n OvercontextAPI,\n BaseEntity,\n} from '@utilarium/overcontext';\nimport {\n redaksjonSchemas,\n redaksjonPluralNames,\n} from '../schemas';\nimport type {\n Person,\n Project,\n Company,\n Term,\n IgnoredTerm,\n RedaksjonEntity,\n RedaksjonEntityType,\n} from '../types';\n// eslint-disable-next-line no-restricted-imports\nimport { existsSync, statSync, readdirSync } from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Entity filename strategy: first 8 chars of UUID + slug.\n * Produces filenames like `d00acdc4-gerald-corson.yaml`.\n * Falls back to entity.id when no slug is present.\n */\nexport const redaksjonFilenameStrategy = (entity: BaseEntity): string => {\n const slug = (entity as RedaksjonEntity & { slug?: string }).slug;\n if (slug) {\n const prefix = entity.id.substring(0, 8);\n return `${prefix}-${slug}`;\n }\n return entity.id;\n};\n\n// Re-export types for backwards compatibility\nexport type { Person, Project, Company, Term, IgnoredTerm, RedaksjonEntity };\nexport type EntityType = RedaksjonEntityType;\nexport type Entity = RedaksjonEntity;\n\n/**\n * StorageInstance interface - matches protokoll's current API.\n */\nexport interface StorageInstance {\n load(contextDirs: string[]): Promise<void>;\n save(entity: Entity, targetDir: string, allowUpdate?: boolean): Promise<void>;\n delete(type: EntityType, id: string, targetDir: string): Promise<boolean>;\n get<T extends Entity>(type: EntityType, id: string): T | undefined;\n getAll<T extends Entity>(type: EntityType): T[];\n search(query: string): Entity[];\n findBySoundsLike(phonetic: string): Entity | undefined;\n clear(): void;\n getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined;\n}\n\n/**\n * Create a storage instance backed by overcontext.\n * Maintains API compatibility with protokoll's existing storage.\n */\n// Map entity types to their directory names\nconst TYPE_TO_DIRECTORY: Record<EntityType, string> = {\n person: 'people',\n project: 'projects',\n company: 'companies',\n term: 'terms',\n ignored: 'ignored',\n};\n\nexport const create = (): StorageInstance => {\n // In-memory cache for sync access (matching original behavior)\n const cache = new Map<EntityType, Map<string, Entity>>();\n let api: OvercontextAPI<typeof redaksjonSchemas> | undefined;\n let loadedContextDirs: string[] = [];\n \n const initCache = () => {\n cache.set('person', new Map());\n cache.set('project', new Map());\n cache.set('company', new Map());\n cache.set('term', new Map());\n cache.set('ignored', new Map());\n };\n \n initCache();\n \n return {\n async load(contextDirs: string[]): Promise<void> {\n initCache();\n loadedContextDirs = contextDirs;\n \n // If no context directories, leave API undefined (empty context)\n if (contextDirs.length === 0) {\n api = undefined;\n return;\n }\n \n try {\n // contextDirs are already resolved paths (e.g., /path/to/context or /path/to/.protokoll/context)\n // We need to determine the parent directory to start overcontext discovery from\n // The context directory could be at different levels depending on configuration\n \n // Take the last (most specific) context dir\n const lastContextDir = contextDirs[contextDirs.length - 1];\n \n // Get the parent directory of the context directory\n // This will be the directory containing the context/ folder\n const startDir = path.dirname(lastContextDir);\n \n // Create overcontext API with hierarchical discovery\n // Note: We use 'context' as contextDirName since we're starting from the parent\n // Use maxLevels: 1 to limit discovery - we've already done hierarchical discovery\n // in loadHierarchicalConfig and are passing the specific contextDirs we want.\n // maxLevels: 1 prevents walking too far up the tree in CI environments where\n // parent directories might contain unrelated context data.\n api = await discoverOvercontext({\n schemas: redaksjonSchemas,\n pluralNames: redaksjonPluralNames,\n startDir,\n contextDirName: path.basename(lastContextDir),\n maxLevels: 1,\n filenameStrategy: redaksjonFilenameStrategy,\n });\n \n // Load all entities into cache\n for (const type of ['person', 'project', 'company', 'term', 'ignored'] as EntityType[]) {\n const entities = await api.getAll(type);\n for (const entity of entities) {\n cache.get(type)?.set(entity.id, entity as Entity);\n }\n }\n } catch (error) {\n // If no context directory found, leave API undefined (empty context)\n if (error instanceof Error && error.message.includes('No context directory found')) {\n api = undefined;\n } else {\n throw error;\n }\n }\n },\n \n async save(entity: Entity, _targetDir: string, allowUpdate = false): Promise<void> {\n // Check if entity already exists (for duplicate detection)\n const existing = cache.get(entity.type)?.get(entity.id);\n if (existing && !allowUpdate) {\n throw new Error(`Entity with id \"${entity.id}\" already exists`);\n }\n\n // If no API (empty context), just update cache (in-memory only)\n if (!api) {\n cache.get(entity.type)?.set(entity.id, entity);\n return;\n }\n \n // Save via overcontext (upsert will create or update)\n const saved = await api.upsert(entity.type, entity);\n \n // Update cache\n cache.get(entity.type)?.set(saved.id, saved as Entity);\n },\n \n async delete(type: EntityType, id: string, _targetDir: string): Promise<boolean> {\n if (!api) return false;\n \n const deleted = await api.delete(type, id);\n if (deleted) {\n cache.get(type)?.delete(id);\n }\n return deleted;\n },\n \n get<T extends Entity>(type: EntityType, id: string): T | undefined {\n return cache.get(type)?.get(id) as T | undefined;\n },\n \n getAll<T extends Entity>(type: EntityType): T[] {\n return Array.from(cache.get(type)?.values() ?? []) as T[];\n },\n \n search(query: string): Entity[] {\n const normalizedQuery = query.toLowerCase();\n const results: Entity[] = [];\n const seen = new Set<string>();\n \n for (const entityMap of cache.values()) {\n for (const entity of entityMap.values()) {\n if (seen.has(entity.id)) continue;\n \n // Check name\n if (entity.name.toLowerCase().includes(normalizedQuery)) {\n results.push(entity);\n seen.add(entity.id);\n continue;\n }\n \n // Check sounds_like\n const sounds = (entity as Entity & { sounds_like?: string[] }).sounds_like;\n if (sounds?.some((s: string) => s.toLowerCase().includes(normalizedQuery))) {\n results.push(entity);\n seen.add(entity.id);\n }\n }\n }\n \n return results;\n },\n \n findBySoundsLike(phonetic: string): Entity | undefined {\n const normalized = phonetic.toLowerCase().trim();\n \n for (const entityMap of cache.values()) {\n for (const entity of entityMap.values()) {\n const sounds = (entity as Entity & { sounds_like?: string[] }).sounds_like;\n if (sounds?.some((s: string) => s.toLowerCase() === normalized)) {\n return entity;\n }\n }\n }\n \n return undefined;\n },\n \n clear(): void {\n initCache();\n api = undefined;\n },\n \n getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined {\n const dirName = TYPE_TO_DIRECTORY[type];\n const dirsToSearch = contextDirs.length > 0 ? contextDirs : loadedContextDirs;\n const entity = cache.get(type)?.get(id);\n \n for (const contextDir of [...dirsToSearch].reverse()) {\n const entityDir = path.join(contextDir, dirName);\n\n // Try compound filename first (e.g. d00acdc4-gerald-corson.yaml)\n if (entity) {\n const compoundName = redaksjonFilenameStrategy(entity as RedaksjonEntity & { slug?: string });\n for (const ext of ['.yaml', '.yml']) {\n const filePath = path.join(entityDir, `${compoundName}${ext}`);\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n return filePath;\n }\n }\n }\n\n // Fall back to direct id-based filename (legacy)\n for (const ext of ['.yaml', '.yml']) {\n const filePath = path.join(entityDir, `${id}${ext}`);\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n return filePath;\n }\n }\n\n // Prefix scan as last resort (handles files we haven't cached yet)\n if (existsSync(entityDir)) {\n const prefix = id.substring(0, 8);\n try {\n const files = readdirSync(entityDir);\n const match = files.find(f =>\n f.startsWith(prefix) && (f.endsWith('.yaml') || f.endsWith('.yml'))\n );\n if (match) {\n return path.join(entityDir, match);\n }\n } catch { /* directory read failed */ }\n }\n }\n \n return undefined;\n },\n };\n};\n"],"names":["path","discoverOvercontext","redaksjonSchemas","redaksjonPluralNames","existsSync","statSync","readdirSync"],"mappings":"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"}
1
+ {"version":3,"file":"index5.cjs","sources":["../src/storage/adapter.ts"],"sourcesContent":["import { \n discoverOvercontext, \n OvercontextAPI,\n BaseEntity,\n createContext as createOvercontextContext,\n createFjellGcsProvider,\n createSchemaRegistry,\n} from '@utilarium/overcontext';\nimport {\n redaksjonSchemas,\n redaksjonPluralNames,\n} from '../schemas';\nimport type {\n Person,\n Project,\n Company,\n Term,\n IgnoredTerm,\n RedaksjonEntity,\n RedaksjonEntityType,\n} from '../types';\nimport { existsSync, statSync, readdirSync } from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Entity filename strategy: first 8 chars of UUID + slug.\n * Produces filenames like `d00acdc4-gerald-corson.yaml`.\n * Falls back to entity.id when no slug is present.\n */\nexport const redaksjonFilenameStrategy = (entity: BaseEntity): string => {\n const slug = (entity as RedaksjonEntity & { slug?: string }).slug;\n if (slug) {\n const prefix = entity.id.substring(0, 8);\n return `${prefix}-${slug}`;\n }\n return entity.id;\n};\n\n// Re-export types for backwards compatibility\nexport type { Person, Project, Company, Term, IgnoredTerm, RedaksjonEntity };\nexport type EntityType = RedaksjonEntityType;\nexport type Entity = RedaksjonEntity;\n\n/**\n * StorageInstance interface - matches protokoll's current API.\n */\nexport interface StorageInstance {\n load(contextDirs: string[]): Promise<void>;\n save(entity: Entity, targetDir: string, allowUpdate?: boolean): Promise<void>;\n delete(type: EntityType, id: string, targetDir: string): Promise<boolean>;\n get<T extends Entity>(type: EntityType, id: string): T | undefined;\n getAll<T extends Entity>(type: EntityType): T[];\n search(query: string): Entity[];\n findBySoundsLike(phonetic: string): Entity | undefined;\n clear(): void;\n getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined;\n}\n\nexport interface GcsStorageOptions {\n bucketName: string;\n basePath: string;\n credentialsFile?: string;\n}\n\nexport interface AdapterCreateOptions {\n gcs?: GcsStorageOptions;\n}\n\n/**\n * Create a storage instance backed by overcontext.\n * Maintains API compatibility with protokoll's existing storage.\n */\n// Map entity types to their directory names\nconst TYPE_TO_DIRECTORY: Record<EntityType, string> = {\n person: 'people',\n project: 'projects',\n company: 'companies',\n term: 'terms',\n ignored: 'ignored',\n};\n\nexport const create = (options: AdapterCreateOptions = {}): StorageInstance => {\n // In-memory cache for sync access (matching original behavior)\n const cache = new Map<EntityType, Map<string, Entity>>();\n let api: OvercontextAPI<typeof redaksjonSchemas> | undefined;\n let loadedContextDirs: string[] = [];\n \n const initCache = () => {\n cache.set('person', new Map());\n cache.set('project', new Map());\n cache.set('company', new Map());\n cache.set('term', new Map());\n cache.set('ignored', new Map());\n };\n \n initCache();\n \n return {\n async load(contextDirs: string[]): Promise<void> {\n initCache();\n loadedContextDirs = contextDirs;\n \n // If no context directories, leave API undefined (empty context)\n if (contextDirs.length === 0) {\n api = undefined;\n return;\n }\n \n try {\n if (options.gcs) {\n const registry = createSchemaRegistry();\n for (const [type, schema] of Object.entries(redaksjonSchemas)) {\n registry.register({\n type,\n schema,\n pluralName: redaksjonPluralNames[type as RedaksjonEntityType] ?? `${type}s`,\n });\n }\n if (options.gcs.credentialsFile && !process.env.GOOGLE_APPLICATION_CREDENTIALS) {\n process.env.GOOGLE_APPLICATION_CREDENTIALS = options.gcs.credentialsFile;\n }\n const provider = await createFjellGcsProvider({\n bucketName: options.gcs.bucketName,\n basePath: options.gcs.basePath,\n registry,\n });\n api = createOvercontextContext({\n provider,\n registry,\n schemas: redaksjonSchemas,\n });\n } else {\n // contextDirs are already resolved paths (e.g., /path/to/context or /path/to/.protokoll/context)\n // We need to determine the parent directory to start overcontext discovery from\n // The context directory could be at different levels depending on configuration\n\n // Take the last (most specific) context dir\n const lastContextDir = contextDirs[contextDirs.length - 1];\n\n // Get the parent directory of the context directory\n // This will be the directory containing the context/ folder\n const startDir = path.dirname(lastContextDir);\n\n // Create overcontext API with hierarchical discovery\n // Note: We use 'context' as contextDirName since we're starting from the parent\n // Use maxLevels: 1 to limit discovery - we've already done hierarchical discovery\n // in loadHierarchicalConfig and are passing the specific contextDirs we want.\n // maxLevels: 1 prevents walking too far up the tree in CI environments where\n // parent directories might contain unrelated context data.\n api = await discoverOvercontext({\n schemas: redaksjonSchemas,\n pluralNames: redaksjonPluralNames,\n startDir,\n contextDirName: path.basename(lastContextDir),\n maxLevels: 1,\n filenameStrategy: redaksjonFilenameStrategy,\n });\n }\n \n // Load all entities into cache\n for (const type of ['person', 'project', 'company', 'term', 'ignored'] as EntityType[]) {\n const entities = await api.getAll(type);\n for (const entity of entities) {\n cache.get(type)?.set(entity.id, entity as Entity);\n }\n }\n } catch (error) {\n // If no context directory found, leave API undefined (empty context)\n if (error instanceof Error && error.message.includes('No context directory found')) {\n api = undefined;\n } else {\n throw error;\n }\n }\n },\n \n async save(entity: Entity, _targetDir: string, allowUpdate = false): Promise<void> {\n // Check if entity already exists (for duplicate detection)\n const existing = cache.get(entity.type)?.get(entity.id);\n if (existing && !allowUpdate) {\n throw new Error(`Entity with id \"${entity.id}\" already exists`);\n }\n\n // If no API (empty context), just update cache (in-memory only)\n if (!api) {\n cache.get(entity.type)?.set(entity.id, entity);\n return;\n }\n \n // Save via overcontext (upsert will create or update)\n const saved = await api.upsert(entity.type, entity);\n \n // Update cache\n cache.get(entity.type)?.set(saved.id, saved as Entity);\n },\n \n async delete(type: EntityType, id: string, _targetDir: string): Promise<boolean> {\n if (!api) return false;\n \n const deleted = await api.delete(type, id);\n if (deleted) {\n cache.get(type)?.delete(id);\n }\n return deleted;\n },\n \n get<T extends Entity>(type: EntityType, id: string): T | undefined {\n return cache.get(type)?.get(id) as T | undefined;\n },\n \n getAll<T extends Entity>(type: EntityType): T[] {\n return Array.from(cache.get(type)?.values() ?? []) as T[];\n },\n \n search(query: string): Entity[] {\n const normalizedQuery = query.toLowerCase();\n const results: Entity[] = [];\n const seen = new Set<string>();\n \n for (const entityMap of cache.values()) {\n for (const entity of entityMap.values()) {\n if (seen.has(entity.id)) continue;\n \n // Check name\n if (entity.name.toLowerCase().includes(normalizedQuery)) {\n results.push(entity);\n seen.add(entity.id);\n continue;\n }\n \n // Check sounds_like\n const sounds = (entity as Entity & { sounds_like?: string[] }).sounds_like;\n if (sounds?.some((s: string) => s.toLowerCase().includes(normalizedQuery))) {\n results.push(entity);\n seen.add(entity.id);\n }\n }\n }\n \n return results;\n },\n \n findBySoundsLike(phonetic: string): Entity | undefined {\n const normalized = phonetic.toLowerCase().trim();\n \n for (const entityMap of cache.values()) {\n for (const entity of entityMap.values()) {\n const sounds = (entity as Entity & { sounds_like?: string[] }).sounds_like;\n if (sounds?.some((s: string) => s.toLowerCase() === normalized)) {\n return entity;\n }\n }\n }\n \n return undefined;\n },\n \n clear(): void {\n initCache();\n api = undefined;\n },\n \n getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined {\n if (options.gcs) {\n // GCS-backed storage does not expose local file paths.\n return undefined;\n }\n\n const dirName = TYPE_TO_DIRECTORY[type];\n const dirsToSearch = contextDirs.length > 0 ? contextDirs : loadedContextDirs;\n const entity = cache.get(type)?.get(id);\n \n for (const contextDir of [...dirsToSearch].reverse()) {\n const entityDir = path.join(contextDir, dirName);\n\n // Try compound filename first (e.g. d00acdc4-gerald-corson.yaml)\n if (entity) {\n const compoundName = redaksjonFilenameStrategy(entity as RedaksjonEntity & { slug?: string });\n for (const ext of ['.yaml', '.yml']) {\n const filePath = path.join(entityDir, `${compoundName}${ext}`);\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n return filePath;\n }\n }\n }\n\n // Fall back to direct id-based filename (legacy)\n for (const ext of ['.yaml', '.yml']) {\n const filePath = path.join(entityDir, `${id}${ext}`);\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n return filePath;\n }\n }\n\n // Prefix scan as last resort (handles files we haven't cached yet)\n if (existsSync(entityDir)) {\n const prefix = id.substring(0, 8);\n try {\n const files = readdirSync(entityDir);\n const match = files.find(f =>\n f.startsWith(prefix) && (f.endsWith('.yaml') || f.endsWith('.yml'))\n );\n if (match) {\n return path.join(entityDir, match);\n }\n } catch { /* directory read failed */ }\n }\n }\n \n return undefined;\n },\n };\n};\n"],"names":["createSchemaRegistry","redaksjonSchemas","redaksjonPluralNames","createFjellGcsProvider","createOvercontextContext","path","discoverOvercontext","existsSync","statSync","readdirSync"],"mappings":"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"}
package/dist/index5.js CHANGED
@@ -1,5 +1,5 @@
1
- import { discoverOvercontext } from '@utilarium/overcontext';
2
- import { redaksjonPluralNames, redaksjonSchemas } from './index2.js';
1
+ import { createSchemaRegistry, createFjellGcsProvider, createContext, discoverOvercontext } from '@utilarium/overcontext';
2
+ import { redaksjonSchemas, redaksjonPluralNames } from './index2.js';
3
3
  import { existsSync, statSync, readdirSync } from 'node:fs';
4
4
  import * as path from 'node:path';
5
5
 
@@ -18,7 +18,7 @@ const TYPE_TO_DIRECTORY = {
18
18
  term: "terms",
19
19
  ignored: "ignored"
20
20
  };
21
- const create = () => {
21
+ const create = (options = {}) => {
22
22
  const cache = /* @__PURE__ */ new Map();
23
23
  let api;
24
24
  let loadedContextDirs = [];
@@ -39,16 +39,40 @@ const create = () => {
39
39
  return;
40
40
  }
41
41
  try {
42
- const lastContextDir = contextDirs[contextDirs.length - 1];
43
- const startDir = path.dirname(lastContextDir);
44
- api = await discoverOvercontext({
45
- schemas: redaksjonSchemas,
46
- pluralNames: redaksjonPluralNames,
47
- startDir,
48
- contextDirName: path.basename(lastContextDir),
49
- maxLevels: 1,
50
- filenameStrategy: redaksjonFilenameStrategy
51
- });
42
+ if (options.gcs) {
43
+ const registry = createSchemaRegistry();
44
+ for (const [type, schema] of Object.entries(redaksjonSchemas)) {
45
+ registry.register({
46
+ type,
47
+ schema,
48
+ pluralName: redaksjonPluralNames[type] ?? `${type}s`
49
+ });
50
+ }
51
+ if (options.gcs.credentialsFile && !process.env.GOOGLE_APPLICATION_CREDENTIALS) {
52
+ process.env.GOOGLE_APPLICATION_CREDENTIALS = options.gcs.credentialsFile;
53
+ }
54
+ const provider = await createFjellGcsProvider({
55
+ bucketName: options.gcs.bucketName,
56
+ basePath: options.gcs.basePath,
57
+ registry
58
+ });
59
+ api = createContext({
60
+ provider,
61
+ registry,
62
+ schemas: redaksjonSchemas
63
+ });
64
+ } else {
65
+ const lastContextDir = contextDirs[contextDirs.length - 1];
66
+ const startDir = path.dirname(lastContextDir);
67
+ api = await discoverOvercontext({
68
+ schemas: redaksjonSchemas,
69
+ pluralNames: redaksjonPluralNames,
70
+ startDir,
71
+ contextDirName: path.basename(lastContextDir),
72
+ maxLevels: 1,
73
+ filenameStrategy: redaksjonFilenameStrategy
74
+ });
75
+ }
52
76
  for (const type of ["person", "project", "company", "term", "ignored"]) {
53
77
  const entities = await api.getAll(type);
54
78
  for (const entity of entities) {
@@ -127,6 +151,9 @@ const create = () => {
127
151
  api = void 0;
128
152
  },
129
153
  getEntityFilePath(type, id, contextDirs) {
154
+ if (options.gcs) {
155
+ return void 0;
156
+ }
130
157
  const dirName = TYPE_TO_DIRECTORY[type];
131
158
  const dirsToSearch = contextDirs.length > 0 ? contextDirs : loadedContextDirs;
132
159
  const entity = cache.get(type)?.get(id);
@@ -1 +1 @@
1
- {"version":3,"file":"index5.js","sources":["../src/storage/adapter.ts"],"sourcesContent":["import { \n discoverOvercontext, \n OvercontextAPI,\n BaseEntity,\n} from '@utilarium/overcontext';\nimport {\n redaksjonSchemas,\n redaksjonPluralNames,\n} from '../schemas';\nimport type {\n Person,\n Project,\n Company,\n Term,\n IgnoredTerm,\n RedaksjonEntity,\n RedaksjonEntityType,\n} from '../types';\n// eslint-disable-next-line no-restricted-imports\nimport { existsSync, statSync, readdirSync } from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Entity filename strategy: first 8 chars of UUID + slug.\n * Produces filenames like `d00acdc4-gerald-corson.yaml`.\n * Falls back to entity.id when no slug is present.\n */\nexport const redaksjonFilenameStrategy = (entity: BaseEntity): string => {\n const slug = (entity as RedaksjonEntity & { slug?: string }).slug;\n if (slug) {\n const prefix = entity.id.substring(0, 8);\n return `${prefix}-${slug}`;\n }\n return entity.id;\n};\n\n// Re-export types for backwards compatibility\nexport type { Person, Project, Company, Term, IgnoredTerm, RedaksjonEntity };\nexport type EntityType = RedaksjonEntityType;\nexport type Entity = RedaksjonEntity;\n\n/**\n * StorageInstance interface - matches protokoll's current API.\n */\nexport interface StorageInstance {\n load(contextDirs: string[]): Promise<void>;\n save(entity: Entity, targetDir: string, allowUpdate?: boolean): Promise<void>;\n delete(type: EntityType, id: string, targetDir: string): Promise<boolean>;\n get<T extends Entity>(type: EntityType, id: string): T | undefined;\n getAll<T extends Entity>(type: EntityType): T[];\n search(query: string): Entity[];\n findBySoundsLike(phonetic: string): Entity | undefined;\n clear(): void;\n getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined;\n}\n\n/**\n * Create a storage instance backed by overcontext.\n * Maintains API compatibility with protokoll's existing storage.\n */\n// Map entity types to their directory names\nconst TYPE_TO_DIRECTORY: Record<EntityType, string> = {\n person: 'people',\n project: 'projects',\n company: 'companies',\n term: 'terms',\n ignored: 'ignored',\n};\n\nexport const create = (): StorageInstance => {\n // In-memory cache for sync access (matching original behavior)\n const cache = new Map<EntityType, Map<string, Entity>>();\n let api: OvercontextAPI<typeof redaksjonSchemas> | undefined;\n let loadedContextDirs: string[] = [];\n \n const initCache = () => {\n cache.set('person', new Map());\n cache.set('project', new Map());\n cache.set('company', new Map());\n cache.set('term', new Map());\n cache.set('ignored', new Map());\n };\n \n initCache();\n \n return {\n async load(contextDirs: string[]): Promise<void> {\n initCache();\n loadedContextDirs = contextDirs;\n \n // If no context directories, leave API undefined (empty context)\n if (contextDirs.length === 0) {\n api = undefined;\n return;\n }\n \n try {\n // contextDirs are already resolved paths (e.g., /path/to/context or /path/to/.protokoll/context)\n // We need to determine the parent directory to start overcontext discovery from\n // The context directory could be at different levels depending on configuration\n \n // Take the last (most specific) context dir\n const lastContextDir = contextDirs[contextDirs.length - 1];\n \n // Get the parent directory of the context directory\n // This will be the directory containing the context/ folder\n const startDir = path.dirname(lastContextDir);\n \n // Create overcontext API with hierarchical discovery\n // Note: We use 'context' as contextDirName since we're starting from the parent\n // Use maxLevels: 1 to limit discovery - we've already done hierarchical discovery\n // in loadHierarchicalConfig and are passing the specific contextDirs we want.\n // maxLevels: 1 prevents walking too far up the tree in CI environments where\n // parent directories might contain unrelated context data.\n api = await discoverOvercontext({\n schemas: redaksjonSchemas,\n pluralNames: redaksjonPluralNames,\n startDir,\n contextDirName: path.basename(lastContextDir),\n maxLevels: 1,\n filenameStrategy: redaksjonFilenameStrategy,\n });\n \n // Load all entities into cache\n for (const type of ['person', 'project', 'company', 'term', 'ignored'] as EntityType[]) {\n const entities = await api.getAll(type);\n for (const entity of entities) {\n cache.get(type)?.set(entity.id, entity as Entity);\n }\n }\n } catch (error) {\n // If no context directory found, leave API undefined (empty context)\n if (error instanceof Error && error.message.includes('No context directory found')) {\n api = undefined;\n } else {\n throw error;\n }\n }\n },\n \n async save(entity: Entity, _targetDir: string, allowUpdate = false): Promise<void> {\n // Check if entity already exists (for duplicate detection)\n const existing = cache.get(entity.type)?.get(entity.id);\n if (existing && !allowUpdate) {\n throw new Error(`Entity with id \"${entity.id}\" already exists`);\n }\n\n // If no API (empty context), just update cache (in-memory only)\n if (!api) {\n cache.get(entity.type)?.set(entity.id, entity);\n return;\n }\n \n // Save via overcontext (upsert will create or update)\n const saved = await api.upsert(entity.type, entity);\n \n // Update cache\n cache.get(entity.type)?.set(saved.id, saved as Entity);\n },\n \n async delete(type: EntityType, id: string, _targetDir: string): Promise<boolean> {\n if (!api) return false;\n \n const deleted = await api.delete(type, id);\n if (deleted) {\n cache.get(type)?.delete(id);\n }\n return deleted;\n },\n \n get<T extends Entity>(type: EntityType, id: string): T | undefined {\n return cache.get(type)?.get(id) as T | undefined;\n },\n \n getAll<T extends Entity>(type: EntityType): T[] {\n return Array.from(cache.get(type)?.values() ?? []) as T[];\n },\n \n search(query: string): Entity[] {\n const normalizedQuery = query.toLowerCase();\n const results: Entity[] = [];\n const seen = new Set<string>();\n \n for (const entityMap of cache.values()) {\n for (const entity of entityMap.values()) {\n if (seen.has(entity.id)) continue;\n \n // Check name\n if (entity.name.toLowerCase().includes(normalizedQuery)) {\n results.push(entity);\n seen.add(entity.id);\n continue;\n }\n \n // Check sounds_like\n const sounds = (entity as Entity & { sounds_like?: string[] }).sounds_like;\n if (sounds?.some((s: string) => s.toLowerCase().includes(normalizedQuery))) {\n results.push(entity);\n seen.add(entity.id);\n }\n }\n }\n \n return results;\n },\n \n findBySoundsLike(phonetic: string): Entity | undefined {\n const normalized = phonetic.toLowerCase().trim();\n \n for (const entityMap of cache.values()) {\n for (const entity of entityMap.values()) {\n const sounds = (entity as Entity & { sounds_like?: string[] }).sounds_like;\n if (sounds?.some((s: string) => s.toLowerCase() === normalized)) {\n return entity;\n }\n }\n }\n \n return undefined;\n },\n \n clear(): void {\n initCache();\n api = undefined;\n },\n \n getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined {\n const dirName = TYPE_TO_DIRECTORY[type];\n const dirsToSearch = contextDirs.length > 0 ? contextDirs : loadedContextDirs;\n const entity = cache.get(type)?.get(id);\n \n for (const contextDir of [...dirsToSearch].reverse()) {\n const entityDir = path.join(contextDir, dirName);\n\n // Try compound filename first (e.g. d00acdc4-gerald-corson.yaml)\n if (entity) {\n const compoundName = redaksjonFilenameStrategy(entity as RedaksjonEntity & { slug?: string });\n for (const ext of ['.yaml', '.yml']) {\n const filePath = path.join(entityDir, `${compoundName}${ext}`);\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n return filePath;\n }\n }\n }\n\n // Fall back to direct id-based filename (legacy)\n for (const ext of ['.yaml', '.yml']) {\n const filePath = path.join(entityDir, `${id}${ext}`);\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n return filePath;\n }\n }\n\n // Prefix scan as last resort (handles files we haven't cached yet)\n if (existsSync(entityDir)) {\n const prefix = id.substring(0, 8);\n try {\n const files = readdirSync(entityDir);\n const match = files.find(f =>\n f.startsWith(prefix) && (f.endsWith('.yaml') || f.endsWith('.yml'))\n );\n if (match) {\n return path.join(entityDir, match);\n }\n } catch { /* directory read failed */ }\n }\n }\n \n return undefined;\n },\n };\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index5.js","sources":["../src/storage/adapter.ts"],"sourcesContent":["import { \n discoverOvercontext, \n OvercontextAPI,\n BaseEntity,\n createContext as createOvercontextContext,\n createFjellGcsProvider,\n createSchemaRegistry,\n} from '@utilarium/overcontext';\nimport {\n redaksjonSchemas,\n redaksjonPluralNames,\n} from '../schemas';\nimport type {\n Person,\n Project,\n Company,\n Term,\n IgnoredTerm,\n RedaksjonEntity,\n RedaksjonEntityType,\n} from '../types';\nimport { existsSync, statSync, readdirSync } from 'node:fs';\nimport * as path from 'node:path';\n\n/**\n * Entity filename strategy: first 8 chars of UUID + slug.\n * Produces filenames like `d00acdc4-gerald-corson.yaml`.\n * Falls back to entity.id when no slug is present.\n */\nexport const redaksjonFilenameStrategy = (entity: BaseEntity): string => {\n const slug = (entity as RedaksjonEntity & { slug?: string }).slug;\n if (slug) {\n const prefix = entity.id.substring(0, 8);\n return `${prefix}-${slug}`;\n }\n return entity.id;\n};\n\n// Re-export types for backwards compatibility\nexport type { Person, Project, Company, Term, IgnoredTerm, RedaksjonEntity };\nexport type EntityType = RedaksjonEntityType;\nexport type Entity = RedaksjonEntity;\n\n/**\n * StorageInstance interface - matches protokoll's current API.\n */\nexport interface StorageInstance {\n load(contextDirs: string[]): Promise<void>;\n save(entity: Entity, targetDir: string, allowUpdate?: boolean): Promise<void>;\n delete(type: EntityType, id: string, targetDir: string): Promise<boolean>;\n get<T extends Entity>(type: EntityType, id: string): T | undefined;\n getAll<T extends Entity>(type: EntityType): T[];\n search(query: string): Entity[];\n findBySoundsLike(phonetic: string): Entity | undefined;\n clear(): void;\n getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined;\n}\n\nexport interface GcsStorageOptions {\n bucketName: string;\n basePath: string;\n credentialsFile?: string;\n}\n\nexport interface AdapterCreateOptions {\n gcs?: GcsStorageOptions;\n}\n\n/**\n * Create a storage instance backed by overcontext.\n * Maintains API compatibility with protokoll's existing storage.\n */\n// Map entity types to their directory names\nconst TYPE_TO_DIRECTORY: Record<EntityType, string> = {\n person: 'people',\n project: 'projects',\n company: 'companies',\n term: 'terms',\n ignored: 'ignored',\n};\n\nexport const create = (options: AdapterCreateOptions = {}): StorageInstance => {\n // In-memory cache for sync access (matching original behavior)\n const cache = new Map<EntityType, Map<string, Entity>>();\n let api: OvercontextAPI<typeof redaksjonSchemas> | undefined;\n let loadedContextDirs: string[] = [];\n \n const initCache = () => {\n cache.set('person', new Map());\n cache.set('project', new Map());\n cache.set('company', new Map());\n cache.set('term', new Map());\n cache.set('ignored', new Map());\n };\n \n initCache();\n \n return {\n async load(contextDirs: string[]): Promise<void> {\n initCache();\n loadedContextDirs = contextDirs;\n \n // If no context directories, leave API undefined (empty context)\n if (contextDirs.length === 0) {\n api = undefined;\n return;\n }\n \n try {\n if (options.gcs) {\n const registry = createSchemaRegistry();\n for (const [type, schema] of Object.entries(redaksjonSchemas)) {\n registry.register({\n type,\n schema,\n pluralName: redaksjonPluralNames[type as RedaksjonEntityType] ?? `${type}s`,\n });\n }\n if (options.gcs.credentialsFile && !process.env.GOOGLE_APPLICATION_CREDENTIALS) {\n process.env.GOOGLE_APPLICATION_CREDENTIALS = options.gcs.credentialsFile;\n }\n const provider = await createFjellGcsProvider({\n bucketName: options.gcs.bucketName,\n basePath: options.gcs.basePath,\n registry,\n });\n api = createOvercontextContext({\n provider,\n registry,\n schemas: redaksjonSchemas,\n });\n } else {\n // contextDirs are already resolved paths (e.g., /path/to/context or /path/to/.protokoll/context)\n // We need to determine the parent directory to start overcontext discovery from\n // The context directory could be at different levels depending on configuration\n\n // Take the last (most specific) context dir\n const lastContextDir = contextDirs[contextDirs.length - 1];\n\n // Get the parent directory of the context directory\n // This will be the directory containing the context/ folder\n const startDir = path.dirname(lastContextDir);\n\n // Create overcontext API with hierarchical discovery\n // Note: We use 'context' as contextDirName since we're starting from the parent\n // Use maxLevels: 1 to limit discovery - we've already done hierarchical discovery\n // in loadHierarchicalConfig and are passing the specific contextDirs we want.\n // maxLevels: 1 prevents walking too far up the tree in CI environments where\n // parent directories might contain unrelated context data.\n api = await discoverOvercontext({\n schemas: redaksjonSchemas,\n pluralNames: redaksjonPluralNames,\n startDir,\n contextDirName: path.basename(lastContextDir),\n maxLevels: 1,\n filenameStrategy: redaksjonFilenameStrategy,\n });\n }\n \n // Load all entities into cache\n for (const type of ['person', 'project', 'company', 'term', 'ignored'] as EntityType[]) {\n const entities = await api.getAll(type);\n for (const entity of entities) {\n cache.get(type)?.set(entity.id, entity as Entity);\n }\n }\n } catch (error) {\n // If no context directory found, leave API undefined (empty context)\n if (error instanceof Error && error.message.includes('No context directory found')) {\n api = undefined;\n } else {\n throw error;\n }\n }\n },\n \n async save(entity: Entity, _targetDir: string, allowUpdate = false): Promise<void> {\n // Check if entity already exists (for duplicate detection)\n const existing = cache.get(entity.type)?.get(entity.id);\n if (existing && !allowUpdate) {\n throw new Error(`Entity with id \"${entity.id}\" already exists`);\n }\n\n // If no API (empty context), just update cache (in-memory only)\n if (!api) {\n cache.get(entity.type)?.set(entity.id, entity);\n return;\n }\n \n // Save via overcontext (upsert will create or update)\n const saved = await api.upsert(entity.type, entity);\n \n // Update cache\n cache.get(entity.type)?.set(saved.id, saved as Entity);\n },\n \n async delete(type: EntityType, id: string, _targetDir: string): Promise<boolean> {\n if (!api) return false;\n \n const deleted = await api.delete(type, id);\n if (deleted) {\n cache.get(type)?.delete(id);\n }\n return deleted;\n },\n \n get<T extends Entity>(type: EntityType, id: string): T | undefined {\n return cache.get(type)?.get(id) as T | undefined;\n },\n \n getAll<T extends Entity>(type: EntityType): T[] {\n return Array.from(cache.get(type)?.values() ?? []) as T[];\n },\n \n search(query: string): Entity[] {\n const normalizedQuery = query.toLowerCase();\n const results: Entity[] = [];\n const seen = new Set<string>();\n \n for (const entityMap of cache.values()) {\n for (const entity of entityMap.values()) {\n if (seen.has(entity.id)) continue;\n \n // Check name\n if (entity.name.toLowerCase().includes(normalizedQuery)) {\n results.push(entity);\n seen.add(entity.id);\n continue;\n }\n \n // Check sounds_like\n const sounds = (entity as Entity & { sounds_like?: string[] }).sounds_like;\n if (sounds?.some((s: string) => s.toLowerCase().includes(normalizedQuery))) {\n results.push(entity);\n seen.add(entity.id);\n }\n }\n }\n \n return results;\n },\n \n findBySoundsLike(phonetic: string): Entity | undefined {\n const normalized = phonetic.toLowerCase().trim();\n \n for (const entityMap of cache.values()) {\n for (const entity of entityMap.values()) {\n const sounds = (entity as Entity & { sounds_like?: string[] }).sounds_like;\n if (sounds?.some((s: string) => s.toLowerCase() === normalized)) {\n return entity;\n }\n }\n }\n \n return undefined;\n },\n \n clear(): void {\n initCache();\n api = undefined;\n },\n \n getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined {\n if (options.gcs) {\n // GCS-backed storage does not expose local file paths.\n return undefined;\n }\n\n const dirName = TYPE_TO_DIRECTORY[type];\n const dirsToSearch = contextDirs.length > 0 ? contextDirs : loadedContextDirs;\n const entity = cache.get(type)?.get(id);\n \n for (const contextDir of [...dirsToSearch].reverse()) {\n const entityDir = path.join(contextDir, dirName);\n\n // Try compound filename first (e.g. d00acdc4-gerald-corson.yaml)\n if (entity) {\n const compoundName = redaksjonFilenameStrategy(entity as RedaksjonEntity & { slug?: string });\n for (const ext of ['.yaml', '.yml']) {\n const filePath = path.join(entityDir, `${compoundName}${ext}`);\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n return filePath;\n }\n }\n }\n\n // Fall back to direct id-based filename (legacy)\n for (const ext of ['.yaml', '.yml']) {\n const filePath = path.join(entityDir, `${id}${ext}`);\n if (existsSync(filePath) && statSync(filePath).isFile()) {\n return filePath;\n }\n }\n\n // Prefix scan as last resort (handles files we haven't cached yet)\n if (existsSync(entityDir)) {\n const prefix = id.substring(0, 8);\n try {\n const files = readdirSync(entityDir);\n const match = files.find(f =>\n f.startsWith(prefix) && (f.endsWith('.yaml') || f.endsWith('.yml'))\n );\n if (match) {\n return path.join(entityDir, match);\n }\n } catch { /* directory read failed */ }\n }\n }\n \n return undefined;\n },\n };\n};\n"],"names":["createOvercontextContext"],"mappings":"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"}
@@ -32,6 +32,12 @@ export interface CreateOptions {
32
32
  configFileName?: string;
33
33
  /** Explicit context directories to load entities from (bypasses discovery) */
34
34
  contextDirectories?: string[];
35
+ /** Optional GCS-backed context storage configuration */
36
+ gcs?: {
37
+ bucketName: string;
38
+ basePath: string;
39
+ credentialsFile?: string;
40
+ };
35
41
  }
36
42
  /**
37
43
  * Create a new context instance using overcontext
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACH,eAAe,EACf,MAAM,EACN,OAAO,EACP,OAAO,EACP,IAAI,EACJ,WAAW,EACd,MAAM,UAAU,CAAC;AAGlB,OAAO,KAAK,EAER,oBAAoB,EAEvB,MAAM,oBAAoB,CAAC;AAG5B,MAAM,WAAW,eAAe;IAE5B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAGxB,iBAAiB,IAAI,oBAAoB,EAAE,CAAC;IAC5C,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,cAAc,IAAI,MAAM,EAAE,CAAC;IAG3B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC5C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC5C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAEhD,YAAY,IAAI,MAAM,EAAE,CAAC;IACzB,cAAc,IAAI,OAAO,EAAE,CAAC;IAC5B,eAAe,IAAI,OAAO,EAAE,CAAC;IAC7B,WAAW,IAAI,IAAI,EAAE,CAAC;IACtB,aAAa,IAAI,WAAW,EAAE,CAAC;IAG/B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAGjC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,EAAE,CAAC;IACzC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IAGhE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE,CAAC;IAC/E,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IAGvE,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAAC;IAG/D,UAAU,IAAI,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,GAAU,UAAS,aAAkB,KAAG,OAAO,CAAC,eAAe,CAiKjF,CAAC"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/runtime/context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EACH,eAAe,EACf,MAAM,EACN,OAAO,EACP,OAAO,EACP,IAAI,EACJ,WAAW,EACd,MAAM,UAAU,CAAC;AAGlB,OAAO,KAAK,EAER,oBAAoB,EAEvB,MAAM,oBAAoB,CAAC;AAG5B,MAAM,WAAW,eAAe;IAE5B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAGxB,iBAAiB,IAAI,oBAAoB,EAAE,CAAC;IAC5C,SAAS,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,cAAc,IAAI,MAAM,EAAE,CAAC;IAG3B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAC1C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC5C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;IAC5C,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAEhD,YAAY,IAAI,MAAM,EAAE,CAAC;IACzB,cAAc,IAAI,OAAO,EAAE,CAAC;IAC5B,eAAe,IAAI,OAAO,EAAE,CAAC;IAC7B,WAAW,IAAI,IAAI,EAAE,CAAC;IACtB,aAAa,IAAI,WAAW,EAAE,CAAC;IAG/B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAGjC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,EAAE,CAAC;IACzC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAAC;IAGhE,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,eAAe,EAAE,CAAC;IAC/E,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IAGvE,UAAU,CAAC,MAAM,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1E,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxD,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,GAAG,SAAS,CAAC;IAG/D,UAAU,IAAI,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,wDAAwD;IACxD,GAAG,CAAC,EAAE;QACF,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;CACL;AAED;;GAEG;AACH,eAAO,MAAM,MAAM,GAAU,UAAS,aAAkB,KAAG,OAAO,CAAC,eAAe,CA2KjF,CAAC"}
@@ -23,5 +23,13 @@ export interface StorageInstance {
23
23
  clear(): void;
24
24
  getEntityFilePath(type: EntityType, id: string, contextDirs: string[]): string | undefined;
25
25
  }
26
- export declare const create: () => StorageInstance;
26
+ export interface GcsStorageOptions {
27
+ bucketName: string;
28
+ basePath: string;
29
+ credentialsFile?: string;
30
+ }
31
+ export interface AdapterCreateOptions {
32
+ gcs?: GcsStorageOptions;
33
+ }
34
+ export declare const create: (options?: AdapterCreateOptions) => StorageInstance;
27
35
  //# sourceMappingURL=adapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/storage/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,UAAU,EACb,MAAM,wBAAwB,CAAC;AAKhC,OAAO,KAAK,EACR,MAAM,EACN,OAAO,EACP,OAAO,EACP,IAAI,EACJ,WAAW,EACX,eAAe,EACf,mBAAmB,EACtB,MAAM,UAAU,CAAC;AAKlB;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,UAAU,KAAG,MAO9D,CAAC;AAGF,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;AAC7E,MAAM,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAC7C,MAAM,MAAM,MAAM,GAAG,eAAe,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;IACnE,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,CAAC,EAAE,CAAC;IAChD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAChC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,KAAK,IAAI,IAAI,CAAC;IACd,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;CAC5F;AAeD,eAAO,MAAM,MAAM,QAAO,eA0MzB,CAAC"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/storage/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,UAAU,EAIb,MAAM,wBAAwB,CAAC;AAKhC,OAAO,KAAK,EACR,MAAM,EACN,OAAO,EACP,OAAO,EACP,IAAI,EACJ,WAAW,EACX,eAAe,EACf,mBAAmB,EACtB,MAAM,UAAU,CAAC;AAIlB;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,GAAI,QAAQ,UAAU,KAAG,MAO9D,CAAC;AAGF,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC;AAC7E,MAAM,MAAM,UAAU,GAAG,mBAAmB,CAAC;AAC7C,MAAM,MAAM,MAAM,GAAG,eAAe,CAAC;AAErC;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1E,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC;IACnE,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,CAAC,EAAE,CAAC;IAChD,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAChC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACvD,KAAK,IAAI,IAAI,CAAC;IACd,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAAC;CAC5F;AAED,MAAM,WAAW,iBAAiB;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACjC,GAAG,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAeD,eAAO,MAAM,MAAM,GAAI,UAAS,oBAAyB,KAAG,eAuO3D,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redaksjon/context",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "Shared context schemas for redaksjon tools",
5
5
  "type": "module",
6
6
  "repository": {
@@ -49,7 +49,8 @@
49
49
  "prepublishOnly": "npm run clean && npm run build"
50
50
  },
51
51
  "dependencies": {
52
- "@utilarium/overcontext": "^0.0.7",
52
+ "@google-cloud/storage": "^7.19.0",
53
+ "@utilarium/overcontext": "^0.0.8",
53
54
  "js-yaml": "^4.1.0",
54
55
  "zod": "^4.0.0"
55
56
  },