pipe-protocol
Version:
A protocol for large scale Interplanetary Intertool Agent Context
173 lines • 5.08 kB
JavaScript
;
/**
* @file IPFS Client Implementation
* @version 1.0.0
* @status STABLE - DO NOT MODIFY WITHOUT TESTS
* @lastModified 2024-02-04
*
* IPFS client for interacting with IPFS nodes.
*
* IMPORTANT:
* - All modifications must maintain test coverage
* - Handle network errors gracefully
* - Maintain data consistency
* - Respect scope and pinning settings
*
* Functionality:
* - Store data in IPFS with configurable options
* - Retrieve data from IPFS
* - Pin management
* - Scope management (public/private)
* - Mock implementation for testing
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.IPFSClient = void 0;
class IPFSClient {
constructor(config) {
this.storedData = new Map();
this.pinnedCids = new Map(); // scope -> Set<cid>
this.config = config;
// Initialize pinned CIDs for each scope
this.pinnedCids.set('private', new Set());
this.pinnedCids.set('public', new Set());
this.pinnedCids.set('machine', new Set());
this.pinnedCids.set('user', new Set());
}
/**
* Store data in IPFS
*/
async store(data, options) {
const scope = options?.scope || this.config.scope;
const record = {
type: 'data',
content: data,
scope: scope,
pinned: options?.pin ?? this.config.pin,
accessPolicy: { hiddenFromLLM: false },
timestamp: new Date().toISOString()
};
// For testing, we'll use a simple hash of the data as the CID
const cid = `Qm${Buffer.from(JSON.stringify(data)).toString('base64').substring(0, 44)}`;
this.storedData.set(cid, record);
const shouldPin = options?.pin ?? this.config.pin;
if (shouldPin) {
await this.pin(cid, scope);
}
return cid;
}
/**
* Fetch data from IPFS
*/
async fetch(cid, scope) {
const record = this.storedData.get(cid);
if (!record) {
return null;
}
return record.scope === scope ? record.content : null;
}
/**
* Pin data in IPFS
*/
async pin(cid, scope) {
if (!this.storedData.has(cid)) {
throw new Error(`Data not found for CID: ${cid}`);
}
this.pinnedCids.get(scope)?.add(cid);
}
/**
* Unpin data from IPFS
*/
async unpin(cid, scope) {
if (!this.storedData.has(cid)) {
throw new Error(`Data not found for CID: ${cid}`);
}
this.pinnedCids.get(scope)?.delete(cid);
}
/**
* Get pinned CIDs for a scope
*/
async getPinnedCids(scope) {
return Array.from(this.pinnedCids.get(scope) || []);
}
/**
* Get node status
*/
getStatus() {
return {
localNode: true,
publicNode: true
};
}
/**
* Get node info for a scope
*/
async getNodeInfo(scope) {
return {
id: 'QmTest',
addresses: ['/ip4/127.0.0.1/tcp/4001'],
scope
};
}
/**
* Get storage metrics for a scope
*/
async getStorageMetrics(scope) {
const pinnedCids = this.pinnedCids.get(scope);
return {
totalSize: 0, // Mock value
numObjects: pinnedCids?.size || 0
};
}
/**
* Get configuration for a scope
*/
async getConfiguration(scope) {
return {
scope,
endpoint: this.config.endpoint,
timeout: this.config.timeout
};
}
/**
* Replicate data from one scope to another
*/
async replicate(cid, fromScope, toScope) {
const record = this.storedData.get(cid);
if (!record) {
throw new Error(`Data not found for CID: ${cid}`);
}
// Verify the record is in the fromScope
if (record.scope !== fromScope) {
throw new Error(`Record with CID ${cid} is not in scope ${fromScope}`);
}
// Create a new record with the target scope
const newRecord = {
...record,
scope: toScope,
timestamp: new Date().toISOString()
};
// Generate a unique CID for the replicated record by including scope and timestamp
const newCid = `Qm${Buffer.from(JSON.stringify({
content: newRecord.content,
scope: toScope,
timestamp: newRecord.timestamp
})).toString('base64').substring(0, 44)}`;
// Store the record with the new CID
this.storedData.set(newCid, newRecord);
// Pin the new record if the original was pinned
if (this.pinnedCids.get(fromScope)?.has(cid)) {
await this.pin(newCid, toScope);
}
return newCid;
}
/**
* Stop the client and cleanup resources
*/
async stop() {
// Cleanup resources
this.storedData.clear();
this.pinnedCids.clear();
}
}
exports.IPFSClient = IPFSClient;
//# sourceMappingURL=ipfsClient.js.map