@loosechain/collection-core
v0.1.0
Published
Core adapter framework for Loosechain data collection
Readme
@loosechain/collection-core
Core adapter framework for Loosechain data collection and normalization.
Overview
@loosechain/collection-core provides the foundational components for building data collection adapters in the Loosechain ecosystem:
- Adapters — Abstract base class and infrastructure for fetching data from various sources
- Normalizers — Transform raw data into standardized
DataSpecformat - Validators — Ensure
DataSpeccompliance with Loosechain schemas - Provenance — Track evidence and generate cryptographic hashes
- Storage — Persist evidence for audit trails
- Utilities — Rate limiting and other helpers
Installation
npm install @loosechain/collection-coreQuick Start
Creating an Adapter
import { BaseAdapter, AdapterQuery, AdapterResult, DataSpec } from '@loosechain/collection-core';
class MyAdapter extends BaseAdapter {
readonly adapterId = 'my-adapter';
readonly adapterVersion = '1.0.0';
readonly adapterType = 'api';
async fetch(query: AdapterQuery): Promise<AdapterResult> {
// Fetch data from your source
const response = await fetchData(query.source);
return {
success: true,
data: response,
timestamp: new Date().toISOString(),
source: query.source,
};
}
async normalize(raw: AdapterResult, query: AdapterQuery): Promise<DataSpec> {
return {
id: generateId(query.source, raw.timestamp),
label: 'My Data',
sourceKind: 'metric',
metrics: extractMetrics(raw.data),
collectedAt: raw.timestamp,
adapterId: this.adapterId,
adapterVersion: this.adapterVersion,
sourceId: query.source,
};
}
}Using the Adapter Registry
import { AdapterRegistry, AdapterRunner } from '@loosechain/collection-core';
const registry = new AdapterRegistry();
registry.register(new MyAdapter());
const runner = new AdapterRunner(registry);
const spec = await runner.runAdapter('my-adapter', { source: 'https://api.example.com' });Validating DataSpecs
import { validateDataSpec, isValidDataSpec } from '@loosechain/collection-core';
const result = validateDataSpec(mySpec);
if (result.valid) {
console.log('DataSpec is valid!');
} else {
console.error('Validation errors:', result.errors);
}
// Or use the type guard
if (isValidDataSpec(mySpec)) {
// mySpec is typed as DataSpec
}Tracking Evidence
import { EvidenceTracker, hashObject } from '@loosechain/collection-core';
const tracker = new EvidenceTracker();
// Capture API response evidence
const evidence = tracker.captureAPIResponse(apiResponse, 'api-endpoint');
// Verify data against evidence
const isValid = tracker.verify(evidence, apiResponse);API Reference
Adapters
BaseAdapter
Abstract base class for all adapters.
abstract class BaseAdapter {
abstract readonly adapterId: string;
abstract readonly adapterVersion: string;
abstract readonly adapterType: 'web' | 'api' | 'file';
abstract fetch(query: AdapterQuery, options?: AdapterOptions): Promise<AdapterResult>;
abstract normalize(raw: AdapterResult, query: AdapterQuery): Promise<DataSpec>;
validate(spec: DataSpec): boolean;
run(query: AdapterQuery, options?: AdapterOptions): Promise<DataSpec>;
}AdapterRegistry
Manages adapter instances.
class AdapterRegistry {
register(adapter: BaseAdapter): void;
getAdapter(id: string): BaseAdapter | undefined;
listAdapters(): BaseAdapter[];
unregister(id: string): boolean;
}AdapterRunner
Executes adapter operations with retry logic.
class AdapterRunner {
runAdapter(adapterId: string, query: AdapterQuery): Promise<DataSpec>;
runMany(specs: AdapterRunSpec[]): Promise<AdapterRunResult[]>;
}Validators
validateDataSpec
Validates a DataSpec against the schema.
function validateDataSpec(spec: unknown, options?: ValidationOptions): ValidationResult;Provenance
hashObject
Generates deterministic SHA-256 hash.
function hashObject(obj: unknown): string;
function hashString(str: string): string;
function verifyHash(obj: unknown, expectedHash: string): boolean;EvidenceTracker
Captures and verifies evidence.
class EvidenceTracker {
captureAPIResponse(response: unknown, source: string): EvidenceObject;
captureFileHash(filePath: string): Promise<EvidenceObject>;
verify(evidence: EvidenceObject, data: unknown): boolean;
}Storage
EvidenceStore
Interface for evidence storage backends.
interface EvidenceStore {
store(evidence: EvidenceObject): Promise<string>;
get(evidenceId: string): Promise<EvidenceObject | null>;
exists(evidenceId: string): Promise<boolean>;
delete(evidenceId: string): Promise<boolean>;
list(): Promise<string[]>;
}Implementations:
InMemoryEvidenceStore— For testingFilesystemEvidenceStore— For production
Utilities
InMemoryRateLimiter
Token bucket rate limiter.
class InMemoryRateLimiter {
checkLimit(key: string, tokens?: number): Promise<RateLimitResult>;
reset(key: string): Promise<void>;
}Types
interface DataSpec {
id: string;
label: string;
sourceKind: 'report' | 'metric' | 'chart' | 'meta';
metrics: MetricPoint[];
collectedAt: string;
adapterId: string;
adapterVersion: string;
sourceId: string;
sourceHash?: string;
evidence?: EvidenceObject[];
metadata?: Record<string, unknown>;
}
interface MetricPoint {
name: string;
value: number | string;
unit?: string;
timestamp?: string;
confidence?: number;
}License
UNLICENSED — Loosechain AI
