105 lines
3.5 KiB
JavaScript
105 lines
3.5 KiB
JavaScript
// 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
|
|
};
|