mcard-js
Version:
MCard - Content-addressable storage with cryptographic hashing, handle resolution, and vector search for Node.js and browsers
180 lines • 7.92 kB
JavaScript
import { HashValidator } from './hash/HashValidator';
import { GTime } from './GTime';
import { ContentTypeInterpreter } from './ContentTypeInterpreter';
import { createMCardDOTSMetadata } from '../types/dots';
/**
* MCard - Content-addressable data container (The Monad)
*
* ## Category Theory Role: MONAD
*
* MCard is the **Monad** in the MVP Cards categorical hierarchy:
* - **MCard (Monad)**: Data container with `unit` (create) and `bind` (chain)
* - **PCard (Functor)**: Pure transformation, `fmap` over MCard content
* - **VCard (Applicative)**: Context-aware application with pre-conditions
*
* ## Scale-Free Monadic Infrastructure: Spinoza-Leibniz Synthesis
*
* MCard implements the dual philosophical foundation:
*
* | Philosopher | Contribution | MCard Implementation |
* |-------------|--------------|---------------------|
* | **Spinoza** | One Substance (Deus sive Natura) | Fixed 3-field schema (Terminal Object) |
* | **Leibniz** | Infinite Monads (Pre-Established Harmony) | Infinite content-addressed entries |
* | **Both** | No windows / Internal causation | Content-addressing (same hash = same truth) |
*
* This enables **Experimental-Operational Symmetry (EOS)**: same behavior from
* a single user's PKC (100MB) to a planetary LLM registry (1PB).
*
* ## DOTS Vocabulary Role: CARRIER
*
* MCard is the **Carrier** in the Double Operadic Theory of Systems (DOTS).
* - Each MCard is an **Object** in the Carrier category Car(S)
* - Hash-links between MCards are **Morphisms** in Car(S)
* - The Carrier is the category of all actual data/systems
*
* ## Petri Net Role: TOKEN CONTENT
*
* In the Categorical Petri Net model:
* - **MCard content** is what tokens carry
* - **VCard** is the token type (Applicative wrapper)
* - **PCard** is the transition that transforms tokens
*
* ## MVP Cards Architecture: Data Plane
*
* ```
* ┌───────────────────────────────────────────────────────┐
* │ APPLICATION PLANE (VCard) │
* │ Petri Net Token / AuthN/AuthZ / Side Effects │
* └─────────────────────────┬─────────────────────────────┘
* │ (Pre-Condition Check)
* ┌─────────────────────────▼─────────────────────────────┐
* │ CONTROL PLANE (PCard) │
* │ Petri Net Transition / CLM Logic / Pure Function │
* └─────────────────────────┬─────────────────────────────┘
* │ (Content Transformation)
* ┌─────────────────────────▼─────────────────────────────┐
* │ DATA PLANE (MCard) ◀── YOU ARE HERE │
* │ Monad / Content-Addressable / Scale-Free Substrate │
* └───────────────────────────────────────────────────────┘
* ```
*
* ## The Empty Schema Principle (Kenosis)
*
* MCard embodies the Empty Schema Principle:
* - Schema contains NO domain-specific terms (only hash, content, g_time)
* - Domain customization happens via data (INSERT), not schema changes
* - Universal applicability: same structure for ANY domain
* - This emptiness enables universality (Kenosis in code)
*
* ## Three Tables as Irreducible Semiotic Triad
*
* The MCard infrastructure uses three tables (Peirce's semiotics):
* - `card` (Object/Referent): what the content means
* - `handle_registry` (Representamen/Sign): which concept is named
* - `handle_history` (Interpretant): how understanding evolved
*
* ## Functional Requirements
*
* | ID | Requirement | Implementation |
* |----|-------------|----------------|
* | M-1 | Content-addressable via hash | `this.hash = SHA-256(content)` |
* | M-2 | CRD-only (no UPDATE) | Immutable class, `readonly` fields |
* | M-3 | Include g_time for ordering | `this.g_time` field |
* | M-4 | Human-readable content | `getContentAsText()` method |
* | MONAD-1 | Unit (pure) operation | `MCard.create(content)` |
* | MONAD-2 | Bind (chain) operation | `MCard.bind(f)` via hash reference |
* | EOS-M1 | Hash is pure function | No side effects in hash computation |
* | EOS-M2 | Content is immutable | All fields are `readonly` |
*
* @see {@link DOTSRole.CARRIER} for DOTS vocabulary definition
* @see {@link EOSRole.INVARIANT_CONTENT} for EOS role definition
* @see docs/MCard_Impl.md for full implementation specification
*/
export class MCard {
content;
hash;
g_time;
contentType; // Defaulting to specific string or null
hashFunction;
constructor(content, hash, g_time, contentType, hashFunction) {
this.content = content;
this.hash = hash;
this.g_time = g_time;
this.contentType = contentType;
this.hashFunction = hashFunction;
}
/**
* Create a new MCard from content
*/
static async create(content, hashAlgorithm = 'sha256') {
if (content === null || content === undefined) {
throw new Error('Content cannot be null or undefined');
}
const bytes = typeof content === 'string'
? new TextEncoder().encode(content)
: content;
if (bytes.length === 0) {
throw new Error('Content cannot be empty');
}
const hash = await HashValidator.computeHash(bytes, hashAlgorithm);
const g_time = GTime.stampNow(hashAlgorithm);
const contentType = ContentTypeInterpreter.detect(bytes);
return new MCard(bytes, hash, g_time, contentType, hashAlgorithm);
}
/**
* Create an MCard from existing data (e.g., from database)
*/
static fromData(content, hash, g_time) {
const alg = GTime.getHashAlgorithm(g_time);
const contentType = ContentTypeInterpreter.detect(content);
return new MCard(content, hash, g_time, contentType, alg);
}
/**
* Get content as text (UTF-8 decoded)
*/
getContentAsText() {
return new TextDecoder().decode(this.content);
}
/**
* Get content as raw bytes
*/
getContent() {
return this.content;
}
/**
* Convert to plain object
*/
toObject() {
return {
hash: this.hash,
content: this.getContentAsText(),
g_time: this.g_time,
contentType: this.contentType,
hashFunction: this.hashFunction
};
}
/**
* Get DOTS vocabulary metadata for this MCard
*
* Returns the DOTS role information that positions this MCard
* in the Double Operadic Theory of Systems framework.
*
* MCard is always a CARRIER object in the Data Plane.
*
* @param tightRefs - Optional array of prerequisite MCard hashes (vertical composition)
* @param looseRefs - Optional array of alternative MCard hashes (horizontal composition)
* @returns DOTSMetadata describing this card's role in the compositional system
*
* @example
* ```typescript
* const card = await MCard.create('Hello World');
* const meta = card.getDOTSMetadata();
* console.log(meta.role); // 'Carrier'
* console.log(meta.plane); // 'Data'
* ```
*/
getDOTSMetadata(tightRefs = [], looseRefs = []) {
return createMCardDOTSMetadata(tightRefs, looseRefs);
}
}
//# sourceMappingURL=MCard.js.map