// EnergiBridge: Lightweight canonical bridge for interoperability in Open-EnergyMesh MVP // This module provides minimal scaffolding for a CatOpt-like bridge that maps // primitives to a vendor-agnostic contract representation and a Graph-of-Contracts // registry for adapters and data schemas. // DSL contracts for interoperability (local problems, shared variables, etc.) // Load DSL definitions from a minimal contract library. const DSL = require('./dsl_contracts'); class GraphOfContracts { constructor() { this.contracts = new Map(); // contractName -> schema this.adapters = new Map(); // adapterName -> { contractName, adapter } } registerContract(contractName, schema) { this.contracts.set(contractName, schema); } getContract(contractName) { return this.contracts.get(contractName); } registerAdapter(adapterName, contractName, adapter) { this.adapters.set(adapterName, { contractName, adapter }); } getAdapter(adapterName) { return this.adapters.get(adapterName); } } class EnergiBridge { constructor() { this.registry = new GraphOfContracts(); // Seed default contract schemas to bootstrap interoperability this.seedDefaultContracts(); } // Seed a minimal set of canonical contracts and schemas that adapters can target seedDefaultContracts() { // Basic skeleton schemas; can be extended by adapters later this.registry.registerContract('LocalProblem', { type: 'object', properties: { Objects: { type: 'string' }, payload: { type: 'object' } } }); this.registry.registerContract('SharedVariables', { type: 'object', properties: { Morphisms: { type: 'string' }, payload: { type: 'object' } } }); this.registry.registerContract('PlanDelta', { type: 'object', properties: { PlanDelta: { type: 'string' } } }); this.registry.registerContract('DualVariables', { type: 'object' }); this.registry.registerContract('PrivacyBudget', { type: 'object' }); this.registry.registerContract('AuditLog', { type: 'object' }); } // Minimal canonical mapping from a local Open-EnergyMesh primitive to a // CatOpt-like canonical object. The real project would implement richer // mappings; this is a skeleton to bootstrap adapters. static toCanonical(primitive) { if (!primitive) return null; // Heuristic-based mapping: detect common shapes if (primitive.localProblem || primitive.LocalProblem) { const lp = primitive.localProblem || primitive.LocalProblem; return { Objects: 'LocalProblem', payload: lp }; } if (primitive.sharedVariables || primitive.SharedVariables) { const sv = primitive.sharedVariables || primitive.SharedVariables; return { Morphisms: 'SharedVariables', payload: sv }; } // Fallback: wrap as a generic contract element return { Objects: 'Unknown', payload: primitive }; } // Attach metadata to a canonical message payload for replay protection and auditing // meta should be a plain object (e.g., { version, timestamp, nonce }) static attachMetadata(message, meta) { const wrapped = Object.assign({}, message); wrapped._meta = meta ? Object.assign({}, meta) : undefined; return wrapped; } } module.exports = { EnergiBridge, GraphOfContracts, LocalProblem: DSL.LocalProblem, SharedVariables: DSL.SharedVariables, PlanDelta: DSL.PlanDelta, DualVariables: DSL.DualVariables, PrivacyBudget: DSL.PrivacyBudget, AuditLog: DSL.AuditLog };