@topgunbuild/core 0.2.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1597 -52
- package/dist/index.d.ts +1597 -52
- package/dist/index.js +1471 -191
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1418 -190
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -11
- package/LICENSE +0 -97
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/HLC.ts","../src/utils/hash.ts","../src/MerkleTree.ts","../src/LWWMap.ts","../src/ORMapMerkle.ts","../src/ORMapMerkleTree.ts","../src/ORMap.ts","../src/serializer.ts","../src/predicate.ts","../src/schemas.ts","../src/types/WriteConcern.ts"],"sourcesContent":["export interface Timestamp {\n millis: number;\n counter: number;\n nodeId: string;\n}\n\nexport class HLC {\n private lastMillis: number;\n private lastCounter: number;\n private readonly nodeId: string;\n\n // Max allowable drift in milliseconds (1 minute)\n private static readonly MAX_DRIFT = 60000;\n\n constructor(nodeId: string) {\n this.nodeId = nodeId;\n this.lastMillis = 0;\n this.lastCounter = 0;\n }\n\n public get getNodeId(): string {\n return this.nodeId;\n }\n\n /**\n * Generates a new unique timestamp for a local event.\n * Ensures monotonicity: always greater than any previously generated or received timestamp.\n */\n public now(): Timestamp {\n const systemTime = Date.now();\n \n // If local physical time catches up to logical time, reset counter\n if (systemTime > this.lastMillis) {\n this.lastMillis = systemTime;\n this.lastCounter = 0;\n } else {\n // Else, just increment the logical counter\n this.lastCounter++;\n }\n\n return {\n millis: this.lastMillis,\n counter: this.lastCounter,\n nodeId: this.nodeId\n };\n }\n\n /**\n * Updates the local clock based on a received remote timestamp.\n * Must be called whenever a message/event is received from another node.\n */\n public update(remote: Timestamp): void {\n const systemTime = Date.now();\n\n // Validate drift (optional but good practice)\n if (remote.millis > systemTime + HLC.MAX_DRIFT) {\n console.warn(`Clock drift detected: Remote time ${remote.millis} is far ahead of local ${systemTime}`);\n // In strict systems we might reject, but in AP systems we usually accept and fast-forward\n }\n\n const maxMillis = Math.max(this.lastMillis, systemTime, remote.millis);\n\n if (maxMillis === this.lastMillis && maxMillis === remote.millis) {\n // Both clocks are on the same millisecond, take max counter\n this.lastCounter = Math.max(this.lastCounter, remote.counter) + 1;\n } else if (maxMillis === this.lastMillis) {\n // Local logical clock is ahead in millis (or same as remote but remote millis < local)\n this.lastCounter++;\n } else if (maxMillis === remote.millis) {\n // Remote clock is ahead, fast-forward local\n this.lastCounter = remote.counter + 1;\n } else {\n // System time is ahead of both\n this.lastCounter = 0;\n }\n\n this.lastMillis = maxMillis;\n }\n\n /**\n * Compares two timestamps.\n * Returns -1 if a < b, 1 if a > b, 0 if equal.\n */\n public static compare(a: Timestamp, b: Timestamp): number {\n if (a.millis !== b.millis) {\n return a.millis - b.millis;\n }\n if (a.counter !== b.counter) {\n return a.counter - b.counter;\n }\n return a.nodeId.localeCompare(b.nodeId);\n }\n\n /**\n * Serializes timestamp to a string representation (e.g., for storage/network).\n * Format: \"<millis>:<counter>:<nodeId>\"\n */\n public static toString(ts: Timestamp): string {\n return `${ts.millis}:${ts.counter}:${ts.nodeId}`;\n }\n\n /**\n * Parses a string representation back to a Timestamp object.\n */\n public static parse(str: string): Timestamp {\n const parts = str.split(':');\n if (parts.length !== 3) {\n throw new Error(`Invalid timestamp format: ${str}`);\n }\n return {\n millis: parseInt(parts[0], 10),\n counter: parseInt(parts[1], 10),\n nodeId: parts[2]\n };\n }\n}\n","/**\n * Hash utilities for TopGun\n *\n * Uses native xxHash64 when available (via @topgunbuild/native),\n * falls back to FNV-1a for JS-only environments.\n *\n * Phase 3.05: Native Hash Integration\n */\n\n// Try to load native hash module\nlet nativeHash: {\n hashString: (str: string) => number;\n isNativeHashAvailable: () => boolean;\n} | null = null;\n\nlet nativeLoadAttempted = false;\n\nfunction tryLoadNative(): void {\n if (nativeLoadAttempted) return;\n nativeLoadAttempted = true;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n nativeHash = require('@topgunbuild/native');\n } catch {\n // Native module not available, will use FNV-1a fallback\n }\n}\n\n/**\n * FNV-1a Hash implementation for strings.\n * Fast, non-cryptographic, synchronous.\n * Used as fallback when native module is unavailable.\n */\nfunction fnv1aHash(str: string): number {\n let hash = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return hash >>> 0; // Ensure positive 32-bit integer\n}\n\n/**\n * Hash a string to a 32-bit unsigned integer.\n *\n * Uses native xxHash64 (truncated to 32 bits) when available,\n * otherwise falls back to FNV-1a.\n *\n * @param str - String to hash\n * @returns 32-bit unsigned integer hash\n */\nexport function hashString(str: string): number {\n tryLoadNative();\n\n if (nativeHash && nativeHash.isNativeHashAvailable()) {\n return nativeHash.hashString(str);\n }\n\n return fnv1aHash(str);\n}\n\n/**\n * Combines multiple hash numbers into one order-independent hash.\n * Used for combining bucket hashes in Merkle trees.\n *\n * Uses simple sum (with overflow handling) for order-independence.\n *\n * @param hashes - Array of hash values to combine\n * @returns Combined hash as 32-bit unsigned integer\n */\nexport function combineHashes(hashes: number[]): number {\n let result = 0;\n for (const h of hashes) {\n result = (result + h) | 0; // Simple sum with overflow\n }\n return result >>> 0;\n}\n\n/**\n * Check if native hash module is being used.\n * Useful for diagnostics and testing.\n */\nexport function isUsingNativeHash(): boolean {\n tryLoadNative();\n return nativeHash?.isNativeHashAvailable() === true;\n}\n\n/**\n * Force use of FNV-1a hash (for testing/compatibility).\n * After calling this, hashString will always use FNV-1a.\n */\nexport function disableNativeHash(): void {\n nativeHash = null;\n nativeLoadAttempted = true;\n}\n\n/**\n * Re-enable native hash loading (for testing).\n * Resets the load state so native module can be loaded again.\n */\nexport function resetNativeHash(): void {\n nativeHash = null;\n nativeLoadAttempted = false;\n}\n","import { LWWRecord } from './LWWMap';\nimport { hashString } from './utils/hash';\n\nexport interface MerkleNode {\n hash: number;\n children?: { [key: string]: MerkleNode }; // Keyed by bucket index (hex char)\n entries?: Map<string, number>; // Leaf node: Key -> ContentHash\n}\n\n/**\n * A specific implementation of Merkle Tree for syncing LWW-Maps.\n * It uses a Prefix Trie structure based on the hash of the Record Key.\n * \n * Structure:\n * - Level 0: Root\n * - Level 1..N: Buckets based on hex digits of Key Hash.\n * \n * This allows us to quickly identify which \"bucket\" of keys is out of sync.\n */\nexport class MerkleTree {\n private root: MerkleNode;\n private readonly depth: number;\n\n constructor(records: Map<string, LWWRecord<any>> = new Map(), depth: number = 3) {\n this.depth = depth;\n this.root = { hash: 0, children: {} };\n // Build initial tree\n for (const [key, record] of records) {\n this.update(key, record);\n }\n }\n\n /**\n * Incrementally updates the Merkle Tree with a single record.\n * @param key The key of the record\n * @param record The record (value + timestamp)\n */\n public update(key: string, record: LWWRecord<any>) {\n const itemHash = hashString(`${key}:${record.timestamp.millis}:${record.timestamp.counter}:${record.timestamp.nodeId}`);\n // We use the hash of the KEY for routing, so the record stays in the same bucket\n // regardless of timestamp changes.\n const pathHash = hashString(key).toString(16).padStart(8, '0'); \n \n this.updateNode(this.root, key, itemHash, pathHash, 0);\n }\n\n /**\n * Removes a key from the Merkle Tree.\n * Necessary for Garbage Collection of tombstones.\n */\n public remove(key: string) {\n const pathHash = hashString(key).toString(16).padStart(8, '0');\n this.removeNode(this.root, key, pathHash, 0);\n }\n\n private removeNode(node: MerkleNode, key: string, pathHash: string, level: number): number {\n // Leaf Node Logic\n if (level >= this.depth) {\n if (node.entries) {\n node.entries.delete(key);\n \n // Recalculate leaf hash\n let h = 0;\n for (const val of node.entries.values()) {\n h = (h + val) | 0;\n }\n node.hash = h >>> 0;\n }\n return node.hash;\n }\n\n // Intermediate Node Logic\n const bucketChar = pathHash[level];\n if (node.children && node.children[bucketChar]) {\n const childHash = this.removeNode(node.children[bucketChar], key, pathHash, level + 1);\n \n // Optimization: if child is empty/zero, we might want to remove it, but for now just recalc.\n }\n \n // Recalculate this node's hash from children\n let h = 0;\n if (node.children) {\n for (const child of Object.values(node.children)) {\n h = (h + child.hash) | 0;\n }\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n private updateNode(node: MerkleNode, key: string, itemHash: number, pathHash: string, level: number): number {\n // Leaf Node Logic\n if (level >= this.depth) {\n if (!node.entries) node.entries = new Map();\n node.entries.set(key, itemHash);\n \n // Recalculate leaf hash (Sum of item hashes)\n let h = 0;\n for (const val of node.entries.values()) {\n h = (h + val) | 0;\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n // Intermediate Node Logic\n const bucketChar = pathHash[level];\n if (!node.children) node.children = {};\n \n if (!node.children[bucketChar]) {\n node.children[bucketChar] = { hash: 0 };\n }\n \n this.updateNode(node.children[bucketChar], key, itemHash, pathHash, level + 1);\n \n // Recalculate this node's hash from children\n let h = 0;\n for (const child of Object.values(node.children)) {\n h = (h + child.hash) | 0;\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n public getRootHash(): number {\n return this.root.hash;\n }\n\n public getNode(path: string): MerkleNode | undefined {\n let current = this.root;\n for (const char of path) {\n if (!current.children || !current.children[char]) {\n return undefined;\n }\n current = current.children[char];\n }\n return current;\n }\n\n /**\n * Returns the hashes of the children at the given path.\n * Used by the client/server to compare buckets.\n */\n public getBuckets(path: string): Record<string, number> {\n const node = this.getNode(path);\n if (!node || !node.children) return {};\n \n const result: Record<string, number> = {};\n for (const [key, child] of Object.entries(node.children)) {\n result[key] = child.hash;\n }\n return result;\n }\n\n /**\n * For a leaf node (bucket), returns the actual keys it contains.\n * Used to request specific keys when a bucket differs.\n */\n public getKeysInBucket(path: string): string[] {\n const node = this.getNode(path);\n if (!node || !node.entries) return [];\n return Array.from(node.entries.keys());\n }\n}\n","import { HLC, Timestamp } from './HLC';\nimport { MerkleTree } from './MerkleTree';\n\n/**\n * A record in the LWW-Map.\n * Can represent a value or a deletion (tombstone).\n */\nexport interface LWWRecord<V> {\n value: V | null;\n timestamp: Timestamp;\n ttlMs?: number;\n}\n\n/**\n * Last-Write-Wins Map Implementation.\n * This structure guarantees convergence by always keeping the entry with the highest timestamp.\n */\nexport class LWWMap<K, V> {\n private data: Map<K, LWWRecord<V>>;\n private readonly hlc: HLC;\n private listeners: Array<() => void> = [];\n private merkleTree: MerkleTree;\n\n constructor(hlc: HLC) {\n this.hlc = hlc;\n this.data = new Map();\n this.merkleTree = new MerkleTree();\n }\n\n public onChange(callback: () => void): () => void {\n this.listeners.push(callback);\n return () => {\n this.listeners = this.listeners.filter(cb => cb !== callback);\n };\n }\n\n private notify(): void {\n this.listeners.forEach(cb => cb());\n }\n\n public getMerkleTree(): MerkleTree {\n return this.merkleTree;\n }\n\n public get size(): number {\n return this.data.size;\n }\n\n /**\n * Sets a value for a key.\n * Generates a new timestamp using the local HLC.\n */\n public set(key: K, value: V, ttlMs?: number): LWWRecord<V> {\n const timestamp = this.hlc.now();\n const record: LWWRecord<V> = { value, timestamp };\n \n if (ttlMs !== undefined) {\n if (typeof ttlMs !== 'number' || ttlMs <= 0 || !Number.isFinite(ttlMs)) {\n // We could throw, but to be resilient we might just ignore invalid TTL or log warning.\n // Given this is core lib, throwing is safer to alert dev.\n throw new Error('TTL must be a positive finite number');\n }\n record.ttlMs = ttlMs;\n }\n \n // We assume K is string for MerkleTree compatibility in this system\n // If K is not string, we might need to stringify it.\n // The project seems to use string keys for maps.\n this.data.set(key, record);\n this.merkleTree.update(String(key), record);\n \n this.notify();\n return record;\n }\n\n /**\n * Retrieves the value for a key.\n * Returns undefined if key doesn't exist, is a tombstone, or is expired.\n */\n public get(key: K): V | undefined {\n const record = this.data.get(key);\n if (!record || record.value === null) {\n return undefined;\n }\n\n // Check for expiration\n if (record.ttlMs) {\n const now = Date.now();\n if (record.timestamp.millis + record.ttlMs < now) {\n return undefined;\n }\n }\n\n return record.value;\n }\n\n /**\n * Returns the full record (including timestamp).\n * Useful for synchronization.\n */\n public getRecord(key: K): LWWRecord<V> | undefined {\n return this.data.get(key);\n }\n\n /**\n * Removes a key (creates a tombstone).\n */\n public remove(key: K): LWWRecord<V> {\n const timestamp = this.hlc.now();\n const tombstone: LWWRecord<V> = { value: null, timestamp };\n \n this.data.set(key, tombstone);\n this.merkleTree.update(String(key), tombstone);\n \n this.notify();\n return tombstone;\n }\n\n /**\n * Merges a record from a remote source.\n * Returns true if the local state was updated.\n */\n public merge(key: K, remoteRecord: LWWRecord<V>): boolean {\n // Update our clock to ensure causality for future events\n this.hlc.update(remoteRecord.timestamp);\n\n const localRecord = this.data.get(key);\n\n // LWW Logic:\n // 1. If no local record, accept remote.\n // 2. If remote is strictly greater than local, accept remote.\n // 3. If equal, we can arbitrarily choose (e.g. by NodeID) to ensure convergence, \n // but HLC.compare handles nodeId tie-breaking already.\n \n if (!localRecord || HLC.compare(remoteRecord.timestamp, localRecord.timestamp) > 0) {\n this.data.set(key, remoteRecord);\n this.merkleTree.update(String(key), remoteRecord);\n \n this.notify();\n return true;\n }\n\n return false;\n }\n\n /**\n * Garbage Collection: Prunes tombstones older than the specified timestamp.\n * Only removes records that are tombstones (deleted) AND older than the threshold.\n * \n * @param olderThan The timestamp threshold. Tombstones older than this will be removed.\n * @returns The number of tombstones removed.\n */\n public prune(olderThan: Timestamp): K[] {\n const removedKeys: K[] = [];\n \n for (const [key, record] of this.data.entries()) {\n // Only prune tombstones (value === null)\n if (record.value === null) {\n // Check if timestamp is strictly older than the threshold\n // HLC.compare(a, b) returns < 0 if a < b\n if (HLC.compare(record.timestamp, olderThan) < 0) {\n this.data.delete(key);\n this.merkleTree.remove(String(key));\n removedKeys.push(key);\n }\n }\n }\n\n if (removedKeys.length > 0) {\n this.notify();\n }\n\n return removedKeys;\n }\n\n /**\n * Clears all data and tombstones.\n * Resets the MerkleTree.\n */\n public clear(): void {\n this.data.clear();\n this.merkleTree = new MerkleTree();\n this.notify();\n }\n\n /**\n * Returns an iterator over all non-deleted entries.\n */\n public entries(): IterableIterator<[K, V]> {\n const iterator = this.data.entries();\n const now = Date.now();\n \n return {\n [Symbol.iterator]() { return this; },\n next: () => {\n let result = iterator.next();\n while (!result.done) {\n const [key, record] = result.value;\n if (record.value !== null) {\n // Check TTL\n if (record.ttlMs && record.timestamp.millis + record.ttlMs < now) {\n result = iterator.next();\n continue;\n }\n return { value: [key, record.value], done: false };\n }\n result = iterator.next();\n }\n return { value: undefined, done: true };\n }\n };\n }\n\n /**\n * Returns all keys (including tombstones).\n */\n public allKeys(): IterableIterator<K> {\n return this.data.keys();\n }\n}\n","import { ORMapRecord } from './ORMap';\nimport { Timestamp } from './HLC';\nimport { hashString } from './utils/hash';\n\n/**\n * Convert Timestamp to deterministic string for hashing.\n * Format: millis:counter:nodeId\n */\nexport function timestampToString(ts: Timestamp): string {\n return `${ts.millis}:${ts.counter}:${ts.nodeId}`;\n}\n\n/**\n * Stringify a value in a deterministic way for hashing.\n */\nfunction stringifyValue(value: unknown): string {\n if (value === null || value === undefined) {\n return String(value);\n }\n if (typeof value === 'object') {\n // Sort object keys for deterministic JSON\n return JSON.stringify(value, Object.keys(value as Record<string, unknown>).sort());\n }\n return String(value);\n}\n\n/**\n * Hash an ORMap entry (key + all its records).\n * Must be deterministic regardless of insertion order.\n *\n * @param key The key of the entry\n * @param records Map of tag -> record for this key\n * @returns Hash as a number (FNV-1a hash)\n */\nexport function hashORMapEntry<V>(\n key: string,\n records: Map<string, ORMapRecord<V>>\n): number {\n // Sort records by tag for deterministic ordering\n const sortedTags = Array.from(records.keys()).sort();\n\n // Build deterministic string representation\n const parts: string[] = [`key:${key}`];\n\n for (const tag of sortedTags) {\n const record = records.get(tag)!;\n // Include tag, value (JSON-stringified), timestamp, and ttl if present\n const valuePart = stringifyValue(record.value);\n\n let recordStr = `${tag}:${valuePart}:${timestampToString(record.timestamp)}`;\n if (record.ttlMs !== undefined) {\n recordStr += `:ttl=${record.ttlMs}`;\n }\n parts.push(recordStr);\n }\n\n return hashString(parts.join('|'));\n}\n\n/**\n * Hash a single ORMapRecord for comparison.\n * Used when comparing individual records during merge.\n */\nexport function hashORMapRecord<V>(record: ORMapRecord<V>): number {\n const valuePart = stringifyValue(record.value);\n\n let str = `${record.tag}:${valuePart}:${timestampToString(record.timestamp)}`;\n if (record.ttlMs !== undefined) {\n str += `:ttl=${record.ttlMs}`;\n }\n\n return hashString(str);\n}\n\n/**\n * Compare two timestamps.\n * Returns:\n * < 0 if a < b\n * > 0 if a > b\n * = 0 if a == b\n */\nexport function compareTimestamps(a: Timestamp, b: Timestamp): number {\n if (a.millis !== b.millis) {\n return a.millis - b.millis;\n }\n if (a.counter !== b.counter) {\n return a.counter - b.counter;\n }\n return a.nodeId.localeCompare(b.nodeId);\n}\n","import { ORMap, ORMapRecord } from './ORMap';\nimport { hashString, combineHashes } from './utils/hash';\nimport { hashORMapEntry } from './ORMapMerkle';\n\n/**\n * Merkle Node for ORMap.\n * Uses a prefix trie structure based on key hash (similar to LWWMap MerkleTree).\n */\nexport interface ORMapMerkleNode {\n hash: number;\n children?: { [key: string]: ORMapMerkleNode }; // Keyed by bucket index (hex char)\n entries?: Map<string, number>; // Leaf node: Key -> ContentHash\n}\n\n/**\n * A Merkle Tree implementation specifically for ORMap synchronization.\n * Uses a Prefix Trie structure based on the hash of the Record Key.\n *\n * Structure:\n * - Level 0: Root\n * - Level 1..N: Buckets based on hex digits of Key Hash.\n *\n * Key difference from LWWMap MerkleTree:\n * - Each key can have multiple records (tags), so the entry hash includes all records for that key.\n */\nexport class ORMapMerkleTree {\n private root: ORMapMerkleNode;\n private readonly depth: number;\n\n constructor(depth: number = 3) {\n this.depth = depth;\n this.root = { hash: 0, children: {} };\n }\n\n /**\n * Update tree from ORMap data.\n * Rebuilds hashes for all entries in the map.\n */\n updateFromORMap<K, V>(map: ORMap<K, V>): void {\n // Clear and rebuild\n this.root = { hash: 0, children: {} };\n\n // Access internal items through available methods\n // We need to iterate over all keys and get their records\n const snapshot = map.getSnapshot();\n\n for (const [key, records] of snapshot.items) {\n if (records.size > 0) {\n const keyStr = String(key);\n const entryHash = hashORMapEntry(keyStr, records);\n const pathHash = hashString(keyStr).toString(16).padStart(8, '0');\n this.updateNode(this.root, keyStr, entryHash, pathHash, 0);\n }\n }\n }\n\n /**\n * Incrementally update a single key's hash.\n * Call this when records for a key change.\n */\n update<V>(key: string, records: Map<string, ORMapRecord<V>>): void {\n const pathHash = hashString(key).toString(16).padStart(8, '0');\n\n if (records.size === 0) {\n // Key has no records, remove from tree\n this.removeNode(this.root, key, pathHash, 0);\n } else {\n const entryHash = hashORMapEntry(key, records);\n this.updateNode(this.root, key, entryHash, pathHash, 0);\n }\n }\n\n /**\n * Remove a key from the tree.\n * Called when all records for a key are removed.\n */\n remove(key: string): void {\n const pathHash = hashString(key).toString(16).padStart(8, '0');\n this.removeNode(this.root, key, pathHash, 0);\n }\n\n private updateNode(\n node: ORMapMerkleNode,\n key: string,\n entryHash: number,\n pathHash: string,\n level: number\n ): number {\n // Leaf Node Logic\n if (level >= this.depth) {\n if (!node.entries) node.entries = new Map();\n node.entries.set(key, entryHash);\n\n // Recalculate leaf hash (Sum of entry hashes)\n let h = 0;\n for (const val of node.entries.values()) {\n h = (h + val) | 0;\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n // Intermediate Node Logic\n const bucketChar = pathHash[level];\n if (!node.children) node.children = {};\n\n if (!node.children[bucketChar]) {\n node.children[bucketChar] = { hash: 0 };\n }\n\n this.updateNode(node.children[bucketChar], key, entryHash, pathHash, level + 1);\n\n // Recalculate this node's hash from children\n let h = 0;\n for (const child of Object.values(node.children)) {\n h = (h + child.hash) | 0;\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n private removeNode(\n node: ORMapMerkleNode,\n key: string,\n pathHash: string,\n level: number\n ): number {\n // Leaf Node Logic\n if (level >= this.depth) {\n if (node.entries) {\n node.entries.delete(key);\n\n // Recalculate leaf hash\n let h = 0;\n for (const val of node.entries.values()) {\n h = (h + val) | 0;\n }\n node.hash = h >>> 0;\n }\n return node.hash;\n }\n\n // Intermediate Node Logic\n const bucketChar = pathHash[level];\n if (node.children && node.children[bucketChar]) {\n this.removeNode(node.children[bucketChar], key, pathHash, level + 1);\n }\n\n // Recalculate this node's hash from children\n let h = 0;\n if (node.children) {\n for (const child of Object.values(node.children)) {\n h = (h + child.hash) | 0;\n }\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n /**\n * Get the root hash for quick comparison.\n */\n getRootHash(): number {\n return this.root.hash;\n }\n\n /**\n * Get node at a specific path.\n */\n getNode(path: string): ORMapMerkleNode | undefined {\n let current = this.root;\n for (const char of path) {\n if (!current.children || !current.children[char]) {\n return undefined;\n }\n current = current.children[char];\n }\n return current;\n }\n\n /**\n * Returns the hashes of the children at the given path.\n * Used by the client/server to compare buckets.\n */\n getBuckets(path: string): Record<string, number> {\n const node = this.getNode(path);\n if (!node || !node.children) return {};\n\n const result: Record<string, number> = {};\n for (const [key, child] of Object.entries(node.children)) {\n result[key] = child.hash;\n }\n return result;\n }\n\n /**\n * For a leaf node (bucket), returns the actual keys it contains.\n * Used to request specific keys when a bucket differs.\n */\n getKeysInBucket(path: string): string[] {\n const node = this.getNode(path);\n if (!node || !node.entries) return [];\n return Array.from(node.entries.keys());\n }\n\n /**\n * Find keys that differ between this tree and bucket info from remote.\n * Returns keys that:\n * - Exist locally but have different hash on remote\n * - Exist on remote but not locally\n * - Exist locally but not on remote\n */\n findDiffKeys(path: string, remoteEntries: Map<string, number>): Set<string> {\n const diffKeys = new Set<string>();\n const node = this.getNode(path);\n const localEntries = node?.entries || new Map();\n\n // Keys in local but not remote, or different hash\n for (const [key, hash] of localEntries) {\n const remoteHash = remoteEntries.get(key);\n if (remoteHash === undefined || remoteHash !== hash) {\n diffKeys.add(key);\n }\n }\n\n // Keys in remote but not local\n for (const key of remoteEntries.keys()) {\n if (!localEntries.has(key)) {\n diffKeys.add(key);\n }\n }\n\n return diffKeys;\n }\n\n /**\n * Get all entry hashes at a leaf path.\n * Used when sending bucket details to remote.\n */\n getEntryHashes(path: string): Map<string, number> {\n const node = this.getNode(path);\n return node?.entries || new Map();\n }\n\n /**\n * Check if a path leads to a leaf node.\n */\n isLeaf(path: string): boolean {\n const node = this.getNode(path);\n return node !== undefined && node.entries !== undefined && node.entries.size > 0;\n }\n}\n","import { HLC, Timestamp } from './HLC';\nimport { ORMapMerkleTree } from './ORMapMerkleTree';\nimport { compareTimestamps } from './ORMapMerkle';\n\n/**\n * A record in the OR-Map (Observed-Remove Map).\n * Represents a single value instance with a unique tag.\n */\nexport interface ORMapRecord<V> {\n value: V;\n timestamp: Timestamp;\n tag: string; // Unique identifier (UUID + Timestamp)\n ttlMs?: number;\n}\n\n/**\n * Result of merging records for a key.\n */\nexport interface MergeKeyResult {\n added: number;\n updated: number;\n}\n\n/**\n * Snapshot of ORMap internal state for Merkle Tree synchronization.\n */\nexport interface ORMapSnapshot<K, V> {\n items: Map<K, Map<string, ORMapRecord<V>>>;\n tombstones: Set<string>;\n}\n\n/**\n * OR-Map (Observed-Remove Map) Implementation.\n * \n * Acts as a Multimap where each Key holds a Set of Values.\n * Supports concurrent additions to the same key without data loss.\n * \n * Logic:\n * - Add(K, V): Generates a unique tag. Stores (V, tag) under K.\n * - Remove(K, V): Finds all *currently observed* tags for V under K, and moves them to a Remove Set (Tombstones).\n * - Merge: Union of items minus Union of tombstones.\n */\nexport class ORMap<K, V> {\n // Key -> Map<Tag, Record>\n // Stores active records.\n private items: Map<K, Map<string, ORMapRecord<V>>>;\n\n // Set of removed tags (Tombstones).\n private tombstones: Set<string>;\n\n // Set of expired tags (Local only cache for fast filtering)\n // Note: We don't persist this directly, but rely on filtering.\n // For now, we will just filter on get()\n\n private readonly hlc: HLC;\n\n // Merkle Tree for efficient sync\n private merkleTree: ORMapMerkleTree;\n\n constructor(hlc: HLC) {\n this.hlc = hlc;\n this.items = new Map();\n this.tombstones = new Set();\n this.merkleTree = new ORMapMerkleTree();\n }\n\n private listeners: Array<() => void> = [];\n\n public onChange(callback: () => void): () => void {\n this.listeners.push(callback);\n return () => {\n this.listeners = this.listeners.filter(cb => cb !== callback);\n };\n }\n\n private notify(): void {\n this.listeners.forEach(cb => cb());\n }\n\n public get size(): number {\n return this.items.size;\n }\n\n public get totalRecords(): number {\n let count = 0;\n for (const keyMap of this.items.values()) {\n count += keyMap.size;\n }\n return count;\n }\n\n /**\n * Adds a value to the set associated with the key.\n * Generates a unique tag for this specific addition.\n */\n public add(key: K, value: V, ttlMs?: number): ORMapRecord<V> {\n const timestamp = this.hlc.now();\n // Tag must be unique globally. HLC.toString() provides unique string per node+time.\n const tag = HLC.toString(timestamp);\n\n const record: ORMapRecord<V> = {\n value,\n timestamp,\n tag\n };\n\n if (ttlMs !== undefined) {\n if (typeof ttlMs !== 'number' || ttlMs <= 0 || !Number.isFinite(ttlMs)) {\n throw new Error('TTL must be a positive finite number');\n }\n record.ttlMs = ttlMs;\n }\n\n let keyMap = this.items.get(key);\n if (!keyMap) {\n keyMap = new Map();\n this.items.set(key, keyMap);\n }\n\n keyMap.set(tag, record);\n this.updateMerkleTree(key);\n this.notify();\n return record;\n }\n\n /**\n * Removes a specific value from the set associated with the key.\n * Marks all *currently observed* instances of this value as removed (tombstones).\n * Returns the list of tags that were removed (useful for sync).\n */\n public remove(key: K, value: V): string[] {\n const keyMap = this.items.get(key);\n if (!keyMap) return [];\n\n // Find all tags for this value\n const tagsToRemove: string[] = [];\n\n for (const [tag, record] of keyMap.entries()) {\n // Using strict equality. For objects, this requires the exact instance.\n if (record.value === value) {\n tagsToRemove.push(tag);\n }\n }\n\n for (const tag of tagsToRemove) {\n this.tombstones.add(tag);\n keyMap.delete(tag);\n }\n\n if (keyMap.size === 0) {\n this.items.delete(key);\n }\n\n this.updateMerkleTree(key);\n this.notify();\n return tagsToRemove;\n }\n\n /**\n * Clears all data and tombstones.\n */\n public clear(): void {\n this.items.clear();\n this.tombstones.clear();\n this.merkleTree = new ORMapMerkleTree();\n this.notify();\n }\n\n /**\n * Returns all active values for a key.\n * Filters out expired records.\n */\n public get(key: K): V[] {\n const keyMap = this.items.get(key);\n if (!keyMap) return [];\n\n const values: V[] = [];\n const now = Date.now();\n\n for (const [tag, record] of keyMap.entries()) {\n if (!this.tombstones.has(tag)) {\n // Check expiration\n if (record.ttlMs && record.timestamp.millis + record.ttlMs < now) {\n continue;\n }\n values.push(record.value);\n }\n }\n return values;\n }\n\n /**\n * Returns all active records for a key.\n * Useful for persistence and sync.\n * Filters out expired records.\n */\n public getRecords(key: K): ORMapRecord<V>[] {\n const keyMap = this.items.get(key);\n if (!keyMap) return [];\n\n const records: ORMapRecord<V>[] = [];\n const now = Date.now();\n\n for (const [tag, record] of keyMap.entries()) {\n if (!this.tombstones.has(tag)) {\n // Check expiration\n if (record.ttlMs && record.timestamp.millis + record.ttlMs < now) {\n continue;\n }\n records.push(record);\n }\n }\n return records;\n }\n\n /**\n * Returns all tombstone tags.\n */\n public getTombstones(): string[] {\n return Array.from(this.tombstones);\n }\n\n /**\n * Applies a record from a remote source (Sync).\n * Returns true if the record was applied (not tombstoned).\n */\n public apply(key: K, record: ORMapRecord<V>): boolean {\n if (this.tombstones.has(record.tag)) return false;\n\n let keyMap = this.items.get(key);\n if (!keyMap) {\n keyMap = new Map();\n this.items.set(key, keyMap);\n }\n keyMap.set(record.tag, record);\n this.hlc.update(record.timestamp);\n this.updateMerkleTree(key);\n this.notify();\n return true;\n }\n\n /**\n * Applies a tombstone (deletion) from a remote source.\n */\n public applyTombstone(tag: string): void {\n this.tombstones.add(tag);\n // Cleanup active items if present\n for (const [key, keyMap] of this.items) {\n if (keyMap.has(tag)) {\n keyMap.delete(tag);\n if (keyMap.size === 0) this.items.delete(key);\n this.updateMerkleTree(key);\n // We found it, so we can stop searching (tag is unique globally)\n break;\n }\n }\n this.notify();\n }\n\n /**\n * Merges state from another ORMap.\n * - Adds all new tombstones from 'other'.\n * - Adds all new items from 'other' that are not in tombstones.\n * - Updates HLC with observed timestamps.\n */\n public merge(other: ORMap<K, V>): void {\n const changedKeys = new Set<K>();\n\n // 1. Merge tombstones\n for (const tag of other.tombstones) {\n this.tombstones.add(tag);\n }\n\n // 2. Merge items\n for (const [key, otherKeyMap] of other.items) {\n let localKeyMap = this.items.get(key);\n if (!localKeyMap) {\n localKeyMap = new Map();\n this.items.set(key, localKeyMap);\n }\n\n for (const [tag, record] of otherKeyMap) {\n // Only accept if not deleted\n if (!this.tombstones.has(tag)) {\n if (!localKeyMap.has(tag)) {\n localKeyMap.set(tag, record);\n changedKeys.add(key);\n }\n // Always update causality\n this.hlc.update(record.timestamp);\n }\n }\n }\n\n // 3. Cleanup: Remove any local items that are now in the merged tombstones\n for (const [key, localKeyMap] of this.items) {\n for (const tag of localKeyMap.keys()) {\n if (this.tombstones.has(tag)) {\n localKeyMap.delete(tag);\n changedKeys.add(key);\n }\n }\n if (localKeyMap.size === 0) {\n this.items.delete(key);\n }\n }\n\n // Update Merkle Tree for changed keys\n for (const key of changedKeys) {\n this.updateMerkleTree(key);\n }\n\n this.notify();\n }\n\n /**\n * Garbage Collection: Prunes tombstones older than the specified timestamp.\n */\n public prune(olderThan: Timestamp): string[] {\n const removedTags: string[] = [];\n\n for (const tag of this.tombstones) {\n try {\n const timestamp = HLC.parse(tag);\n if (HLC.compare(timestamp, olderThan) < 0) {\n this.tombstones.delete(tag);\n removedTags.push(tag);\n }\n } catch (e) {\n // Ignore invalid tags\n }\n }\n\n return removedTags;\n }\n\n // ============ Merkle Sync Methods ============\n\n /**\n * Get the Merkle Tree for this ORMap.\n * Used for efficient synchronization.\n */\n public getMerkleTree(): ORMapMerkleTree {\n return this.merkleTree;\n }\n\n /**\n * Get a snapshot of internal state for Merkle Tree synchronization.\n * Returns references to internal structures - do not modify!\n */\n public getSnapshot(): ORMapSnapshot<K, V> {\n return {\n items: this.items,\n tombstones: this.tombstones\n };\n }\n\n /**\n * Get all keys in this ORMap.\n */\n public allKeys(): K[] {\n return Array.from(this.items.keys());\n }\n\n /**\n * Get the internal records map for a key.\n * Returns Map<tag, record> or undefined if key doesn't exist.\n * Used for Merkle sync.\n */\n public getRecordsMap(key: K): Map<string, ORMapRecord<V>> | undefined {\n return this.items.get(key);\n }\n\n /**\n * Merge remote records for a specific key into local state.\n * Implements Observed-Remove CRDT semantics.\n * Used during Merkle Tree synchronization.\n *\n * @param key The key to merge\n * @param remoteRecords Array of records from remote\n * @param remoteTombstones Array of tombstone tags from remote\n * @returns Result with count of added and updated records\n */\n public mergeKey(\n key: K,\n remoteRecords: ORMapRecord<V>[],\n remoteTombstones: string[] = []\n ): MergeKeyResult {\n let added = 0;\n let updated = 0;\n\n // First apply remote tombstones\n for (const tag of remoteTombstones) {\n if (!this.tombstones.has(tag)) {\n this.tombstones.add(tag);\n }\n }\n\n // Get or create local key map\n let localKeyMap = this.items.get(key);\n if (!localKeyMap) {\n localKeyMap = new Map();\n this.items.set(key, localKeyMap);\n }\n\n // Remove any local records that are now tombstoned\n for (const tag of localKeyMap.keys()) {\n if (this.tombstones.has(tag)) {\n localKeyMap.delete(tag);\n }\n }\n\n // Merge remote records\n for (const remoteRecord of remoteRecords) {\n // Skip if tombstoned\n if (this.tombstones.has(remoteRecord.tag)) {\n continue;\n }\n\n const localRecord = localKeyMap.get(remoteRecord.tag);\n\n if (!localRecord) {\n // New record - add it\n localKeyMap.set(remoteRecord.tag, remoteRecord);\n added++;\n } else if (compareTimestamps(remoteRecord.timestamp, localRecord.timestamp) > 0) {\n // Remote is newer - update\n localKeyMap.set(remoteRecord.tag, remoteRecord);\n updated++;\n }\n // Else: local is newer or equal, keep local\n\n // Always update causality\n this.hlc.update(remoteRecord.timestamp);\n }\n\n // Cleanup empty key map\n if (localKeyMap.size === 0) {\n this.items.delete(key);\n }\n\n // Update Merkle Tree\n this.updateMerkleTree(key);\n\n if (added > 0 || updated > 0) {\n this.notify();\n }\n\n return { added, updated };\n }\n\n /**\n * Check if a tag is tombstoned.\n */\n public isTombstoned(tag: string): boolean {\n return this.tombstones.has(tag);\n }\n\n /**\n * Update the Merkle Tree for a specific key.\n * Called internally after any modification.\n */\n private updateMerkleTree(key: K): void {\n const keyStr = String(key);\n const keyMap = this.items.get(key);\n\n if (!keyMap || keyMap.size === 0) {\n this.merkleTree.remove(keyStr);\n } else {\n this.merkleTree.update(keyStr, keyMap);\n }\n }\n}\n","import { pack, unpack } from 'msgpackr';\n\n/**\n * Serializes a JavaScript object to MessagePack binary format.\n * Uses msgpackr for 2-5x faster serialization compared to @msgpack/msgpack.\n * @param data The data to serialize.\n * @returns A Uint8Array containing the serialized data.\n */\nexport function serialize(data: unknown): Uint8Array {\n return pack(data);\n}\n\n/**\n * Deserializes MessagePack binary data to a JavaScript object.\n * Uses msgpackr for 2-5x faster deserialization compared to @msgpack/msgpack.\n * @param data The binary data to deserialize (Uint8Array or ArrayBuffer).\n * @returns The deserialized object.\n */\nexport function deserialize<T = unknown>(data: Uint8Array | ArrayBuffer): T {\n // msgpackr unpack accepts Uint8Array, Buffer, ArrayBuffer\n const buffer = data instanceof ArrayBuffer ? new Uint8Array(data) : data;\n return unpack(buffer) as T;\n}\n\n","\nexport type PredicateOp = \n | 'eq' | 'neq' \n | 'gt' | 'gte' \n | 'lt' | 'lte' \n | 'like' | 'regex' \n | 'and' | 'or' | 'not';\n\nexport interface PredicateNode {\n op: PredicateOp;\n attribute?: string;\n value?: any;\n children?: PredicateNode[];\n}\n\nexport class Predicates {\n static equal(attribute: string, value: any): PredicateNode { \n return { op: 'eq', attribute, value }; \n }\n \n static notEqual(attribute: string, value: any): PredicateNode { \n return { op: 'neq', attribute, value }; \n }\n \n static greaterThan(attribute: string, value: any): PredicateNode { \n return { op: 'gt', attribute, value }; \n }\n \n static greaterThanOrEqual(attribute: string, value: any): PredicateNode { \n return { op: 'gte', attribute, value }; \n }\n \n static lessThan(attribute: string, value: any): PredicateNode { \n return { op: 'lt', attribute, value }; \n }\n \n static lessThanOrEqual(attribute: string, value: any): PredicateNode { \n return { op: 'lte', attribute, value }; \n }\n \n static like(attribute: string, pattern: string): PredicateNode { \n return { op: 'like', attribute, value: pattern }; \n }\n \n static regex(attribute: string, pattern: string): PredicateNode { \n return { op: 'regex', attribute, value: pattern }; \n }\n\n static between(attribute: string, from: any, to: any): PredicateNode {\n return {\n op: 'and',\n children: [\n { op: 'gte', attribute, value: from },\n { op: 'lte', attribute, value: to }\n ]\n };\n }\n\n static and(...predicates: PredicateNode[]): PredicateNode { \n return { op: 'and', children: predicates }; \n }\n \n static or(...predicates: PredicateNode[]): PredicateNode { \n return { op: 'or', children: predicates }; \n }\n \n static not(predicate: PredicateNode): PredicateNode { \n return { op: 'not', children: [predicate] }; \n }\n}\n\nexport function evaluatePredicate(predicate: PredicateNode, data: any): boolean {\n if (!data) return false;\n \n switch (predicate.op) {\n case 'and':\n return (predicate.children || []).every(p => evaluatePredicate(p, data));\n case 'or':\n return (predicate.children || []).some(p => evaluatePredicate(p, data));\n case 'not': {\n const child = (predicate.children || [])[0];\n if (!child) return true; // NOT of nothing is true (vacuous)\n return !evaluatePredicate(child, data);\n }\n }\n\n // Leaf nodes require an attribute\n if (!predicate.attribute) return false;\n \n const value = data[predicate.attribute];\n const target = predicate.value;\n\n switch (predicate.op) {\n case 'eq':\n return value === target;\n case 'neq':\n return value !== target;\n case 'gt':\n return value > target;\n case 'gte':\n return value >= target;\n case 'lt':\n return value < target;\n case 'lte':\n return value <= target;\n case 'like':\n if (typeof value !== 'string' || typeof target !== 'string') return false;\n const pattern = target\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/%/g, '.*')\n .replace(/_/g, '.');\n return new RegExp(`^${pattern}$`, 'i').test(value);\n case 'regex':\n if (typeof value !== 'string' || typeof target !== 'string') return false;\n return new RegExp(target).test(value);\n default:\n return false;\n }\n}\n","import { z } from 'zod';\n\n// --- Write Concern Types ---\n\n/**\n * Write Concern schema - defines when an operation is considered acknowledged.\n */\nexport const WriteConcernSchema = z.enum([\n 'FIRE_AND_FORGET',\n 'MEMORY',\n 'APPLIED',\n 'REPLICATED',\n 'PERSISTED',\n]);\n\nexport type WriteConcernValue = z.infer<typeof WriteConcernSchema>;\n\n// --- Basic Types ---\n\nexport const TimestampSchema = z.object({\n millis: z.number(),\n counter: z.number(),\n nodeId: z.string(),\n});\n\nexport const LWWRecordSchema = z.object({\n value: z.any().nullable(),\n timestamp: TimestampSchema,\n ttlMs: z.number().optional(),\n});\n\nexport const ORMapRecordSchema = z.object({\n value: z.any(),\n timestamp: TimestampSchema,\n tag: z.string(),\n ttlMs: z.number().optional(),\n});\n\n// --- Predicate Types ---\n\nexport const PredicateOpSchema = z.enum([\n 'eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'like', 'regex', 'and', 'or', 'not'\n]);\n\n// Recursive schema for PredicateNode\nexport const PredicateNodeSchema: z.ZodType<any> = z.lazy(() => z.object({\n op: PredicateOpSchema,\n attribute: z.string().optional(),\n value: z.any().optional(),\n children: z.array(PredicateNodeSchema).optional(),\n}));\n\n// --- Query Types ---\n\nexport const QuerySchema = z.object({\n where: z.record(z.string(), z.any()).optional(),\n predicate: PredicateNodeSchema.optional(),\n sort: z.record(z.string(), z.enum(['asc', 'desc'])).optional(),\n limit: z.number().optional(),\n offset: z.number().optional(),\n});\n\n// --- Client Operation Types ---\n\nexport const ClientOpSchema = z.object({\n id: z.string().optional(),\n mapName: z.string(),\n key: z.string(),\n // Permissive opType to match ServerCoordinator behavior logic\n // It can be 'REMOVE', 'OR_ADD', 'OR_REMOVE' or undefined/other (implies PUT/LWW)\n opType: z.string().optional(),\n record: LWWRecordSchema.nullable().optional(),\n orRecord: ORMapRecordSchema.nullable().optional(),\n orTag: z.string().nullable().optional(),\n // Write Concern fields (Phase 5.01)\n writeConcern: WriteConcernSchema.optional(),\n timeout: z.number().optional(),\n});\n\n// --- Message Schemas ---\n\nexport const AuthMessageSchema = z.object({\n type: z.literal('AUTH'),\n token: z.string(),\n});\n\nexport const QuerySubMessageSchema = z.object({\n type: z.literal('QUERY_SUB'),\n payload: z.object({\n queryId: z.string(),\n mapName: z.string(),\n query: QuerySchema,\n }),\n});\n\nexport const QueryUnsubMessageSchema = z.object({\n type: z.literal('QUERY_UNSUB'),\n payload: z.object({\n queryId: z.string(),\n }),\n});\n\nexport const ClientOpMessageSchema = z.object({\n type: z.literal('CLIENT_OP'),\n payload: ClientOpSchema,\n});\n\nexport const OpBatchMessageSchema = z.object({\n type: z.literal('OP_BATCH'),\n payload: z.object({\n ops: z.array(ClientOpSchema),\n // Batch-level Write Concern (can be overridden per-op)\n writeConcern: WriteConcernSchema.optional(),\n timeout: z.number().optional(),\n }),\n});\n\nexport const SyncInitMessageSchema = z.object({\n type: z.literal('SYNC_INIT'),\n mapName: z.string(),\n lastSyncTimestamp: z.number().optional(),\n});\n\nexport const SyncRespRootMessageSchema = z.object({\n type: z.literal('SYNC_RESP_ROOT'),\n payload: z.object({\n mapName: z.string(),\n rootHash: z.number(),\n timestamp: TimestampSchema,\n }),\n});\n\nexport const SyncRespBucketsMessageSchema = z.object({\n type: z.literal('SYNC_RESP_BUCKETS'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n buckets: z.record(z.string(), z.number()),\n }),\n});\n\nexport const SyncRespLeafMessageSchema = z.object({\n type: z.literal('SYNC_RESP_LEAF'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n records: z.array(z.object({\n key: z.string(),\n record: LWWRecordSchema,\n })),\n }),\n});\n\nexport const MerkleReqBucketMessageSchema = z.object({\n type: z.literal('MERKLE_REQ_BUCKET'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n }),\n});\n\nexport const LockRequestSchema = z.object({\n type: z.literal('LOCK_REQUEST'),\n payload: z.object({\n requestId: z.string(),\n name: z.string(),\n ttl: z.number().optional(),\n }),\n});\n\nexport const LockReleaseSchema = z.object({\n type: z.literal('LOCK_RELEASE'),\n payload: z.object({\n requestId: z.string().optional(),\n name: z.string(),\n fencingToken: z.number(),\n }),\n});\n\n// --- Topic Messages ---\n\nexport const TopicSubSchema = z.object({\n type: z.literal('TOPIC_SUB'),\n payload: z.object({\n topic: z.string(),\n }),\n});\n\nexport const TopicUnsubSchema = z.object({\n type: z.literal('TOPIC_UNSUB'),\n payload: z.object({\n topic: z.string(),\n }),\n});\n\nexport const TopicPubSchema = z.object({\n type: z.literal('TOPIC_PUB'),\n payload: z.object({\n topic: z.string(),\n data: z.any(),\n }),\n});\n\nexport const TopicMessageEventSchema = z.object({\n type: z.literal('TOPIC_MESSAGE'),\n payload: z.object({\n topic: z.string(),\n data: z.any(),\n publisherId: z.string().optional(),\n timestamp: z.number(),\n }),\n});\n\n// --- Heartbeat Messages ---\n\nexport const PingMessageSchema = z.object({\n type: z.literal('PING'),\n timestamp: z.number(), // Client's Date.now()\n});\n\nexport const PongMessageSchema = z.object({\n type: z.literal('PONG'),\n timestamp: z.number(), // Echo back client's timestamp\n serverTime: z.number(), // Server's Date.now() (for clock skew detection)\n});\n\n// --- Batched Messages ---\n\n/**\n * BATCH: Server sends multiple messages batched together.\n * Uses length-prefixed binary format for efficiency.\n * Format: [4 bytes: count][4 bytes: len1][msg1][4 bytes: len2][msg2]...\n */\nexport const BatchMessageSchema = z.object({\n type: z.literal('BATCH'),\n count: z.number(),\n data: z.instanceof(Uint8Array),\n});\n\n// --- ORMap Sync Messages ---\n\n/**\n * ORMAP_SYNC_INIT: Client initiates ORMap sync\n * Sends root hash and bucket hashes to server\n */\nexport const ORMapSyncInitSchema = z.object({\n type: z.literal('ORMAP_SYNC_INIT'),\n mapName: z.string(),\n rootHash: z.number(),\n bucketHashes: z.record(z.string(), z.number()), // path -> hash\n lastSyncTimestamp: z.number().optional(),\n});\n\n/**\n * ORMAP_SYNC_RESP_ROOT: Server responds with its root hash\n */\nexport const ORMapSyncRespRootSchema = z.object({\n type: z.literal('ORMAP_SYNC_RESP_ROOT'),\n payload: z.object({\n mapName: z.string(),\n rootHash: z.number(),\n timestamp: TimestampSchema,\n }),\n});\n\n/**\n * ORMAP_SYNC_RESP_BUCKETS: Server sends bucket hashes for comparison\n */\nexport const ORMapSyncRespBucketsSchema = z.object({\n type: z.literal('ORMAP_SYNC_RESP_BUCKETS'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n buckets: z.record(z.string(), z.number()),\n }),\n});\n\n/**\n * ORMAP_MERKLE_REQ_BUCKET: Client requests bucket details\n */\nexport const ORMapMerkleReqBucketSchema = z.object({\n type: z.literal('ORMAP_MERKLE_REQ_BUCKET'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n }),\n});\n\n/**\n * ORMAP_SYNC_RESP_LEAF: Server sends actual records for differing keys\n */\nexport const ORMapSyncRespLeafSchema = z.object({\n type: z.literal('ORMAP_SYNC_RESP_LEAF'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n entries: z.array(z.object({\n key: z.string(),\n records: z.array(ORMapRecordSchema),\n tombstones: z.array(z.string()), // Tombstone tags for this key's records\n })),\n }),\n});\n\n/**\n * ORMAP_DIFF_REQUEST: Client requests data for specific keys\n */\nexport const ORMapDiffRequestSchema = z.object({\n type: z.literal('ORMAP_DIFF_REQUEST'),\n payload: z.object({\n mapName: z.string(),\n keys: z.array(z.string()),\n }),\n});\n\n/**\n * ORMAP_DIFF_RESPONSE: Server responds with data for requested keys\n */\nexport const ORMapDiffResponseSchema = z.object({\n type: z.literal('ORMAP_DIFF_RESPONSE'),\n payload: z.object({\n mapName: z.string(),\n entries: z.array(z.object({\n key: z.string(),\n records: z.array(ORMapRecordSchema),\n tombstones: z.array(z.string()),\n })),\n }),\n});\n\n/**\n * ORMAP_PUSH_DIFF: Client pushes local diffs to server\n */\nexport const ORMapPushDiffSchema = z.object({\n type: z.literal('ORMAP_PUSH_DIFF'),\n payload: z.object({\n mapName: z.string(),\n entries: z.array(z.object({\n key: z.string(),\n records: z.array(ORMapRecordSchema),\n tombstones: z.array(z.string()),\n })),\n }),\n});\n\n// --- Write Concern Response Schemas (Phase 5.01) ---\n\n/**\n * Individual operation result within a batch ACK\n */\nexport const OpResultSchema = z.object({\n opId: z.string(),\n success: z.boolean(),\n achievedLevel: WriteConcernSchema,\n error: z.string().optional(),\n});\n\n/**\n * OP_ACK: Server acknowledges write operations\n * Extended to support Write Concern levels\n */\nexport const OpAckMessageSchema = z.object({\n type: z.literal('OP_ACK'),\n payload: z.object({\n /** ID of the last operation in the batch (for backwards compatibility) */\n lastId: z.string(),\n /** Write Concern level achieved (for simple ACKs) */\n achievedLevel: WriteConcernSchema.optional(),\n /** Per-operation results (for batch operations with mixed Write Concern) */\n results: z.array(OpResultSchema).optional(),\n }),\n});\n\n/**\n * OP_REJECTED: Server rejects a write operation\n */\nexport const OpRejectedMessageSchema = z.object({\n type: z.literal('OP_REJECTED'),\n payload: z.object({\n /** Operation ID that was rejected */\n opId: z.string(),\n /** Reason for rejection */\n reason: z.string(),\n /** Error code */\n code: z.number().optional(),\n }),\n});\n\n// --- Union Schema ---\n\nexport const MessageSchema = z.discriminatedUnion('type', [\n AuthMessageSchema,\n QuerySubMessageSchema,\n QueryUnsubMessageSchema,\n ClientOpMessageSchema,\n OpBatchMessageSchema,\n SyncInitMessageSchema,\n SyncRespRootMessageSchema,\n SyncRespBucketsMessageSchema,\n SyncRespLeafMessageSchema,\n MerkleReqBucketMessageSchema,\n LockRequestSchema,\n LockReleaseSchema,\n TopicSubSchema,\n TopicUnsubSchema,\n TopicPubSchema,\n PingMessageSchema,\n PongMessageSchema,\n // ORMap Sync Messages\n ORMapSyncInitSchema,\n ORMapSyncRespRootSchema,\n ORMapSyncRespBucketsSchema,\n ORMapMerkleReqBucketSchema,\n ORMapSyncRespLeafSchema,\n ORMapDiffRequestSchema,\n ORMapDiffResponseSchema,\n ORMapPushDiffSchema,\n]);\n\n// --- Type Inference ---\n\nexport type Timestamp = z.infer<typeof TimestampSchema>;\nexport type LWWRecord<V = any> = z.infer<typeof LWWRecordSchema>; // Generic placeholder\nexport type ORMapRecord<V = any> = z.infer<typeof ORMapRecordSchema>; // Generic placeholder\n// export type PredicateNode = z.infer<typeof PredicateNodeSchema>; // Conflict with predicate.ts\nexport type Query = z.infer<typeof QuerySchema>;\nexport type ClientOp = z.infer<typeof ClientOpSchema>;\nexport type Message = z.infer<typeof MessageSchema>;\nexport type PingMessage = z.infer<typeof PingMessageSchema>;\nexport type PongMessage = z.infer<typeof PongMessageSchema>;\nexport type BatchMessage = z.infer<typeof BatchMessageSchema>;\n\n// Write Concern types (Phase 5.01)\nexport type OpAckMessage = z.infer<typeof OpAckMessageSchema>;\nexport type OpRejectedMessage = z.infer<typeof OpRejectedMessageSchema>;\nexport type OpResult = z.infer<typeof OpResultSchema>;\n\n","/**\n * Write Concern - Configurable Acknowledgment Levels\n *\n * Write Concern defines when a write operation is considered successful.\n * Similar to MongoDB's writeConcern, Kafka's acks, and Cassandra's consistency levels.\n */\n\n/**\n * Write Concern levels - determines when an operation is acknowledged.\n *\n * Levels are ordered by durability guarantee (lowest to highest):\n * FIRE_AND_FORGET < MEMORY < APPLIED < REPLICATED < PERSISTED\n */\nexport enum WriteConcern {\n /**\n * FIRE_AND_FORGET (acks=0)\n * - ACK sent immediately after server receives the message\n * - Operation may be lost if server crashes before processing\n * - Maximum throughput, minimum latency\n * - Use case: metrics, logs, non-critical data\n */\n FIRE_AND_FORGET = 'FIRE_AND_FORGET',\n\n /**\n * MEMORY (acks=1, default) - current Early ACK behavior\n * - ACK sent after validation and queuing for processing\n * - Operation is in memory but not yet applied to CRDT\n * - Use case: most operations, real-time updates\n */\n MEMORY = 'MEMORY',\n\n /**\n * APPLIED\n * - ACK sent after operation is applied to CRDT in memory\n * - Data is readable on this node immediately after ACK\n * - Use case: operations requiring immediate consistency on the node\n */\n APPLIED = 'APPLIED',\n\n /**\n * REPLICATED\n * - ACK sent after operation is broadcast to cluster (CLUSTER_EVENT sent)\n * - Data survives primary node failure\n * - Use case: important data requiring cluster durability\n */\n REPLICATED = 'REPLICATED',\n\n /**\n * PERSISTED\n * - ACK sent after operation is written to storage on primary node\n * - Data survives node restart\n * - Use case: critical data (financial transactions, audit logs)\n */\n PERSISTED = 'PERSISTED',\n}\n\n/**\n * Default timeout for Write Concern acknowledgments (ms)\n */\nexport const DEFAULT_WRITE_CONCERN_TIMEOUT = 5000;\n\n/**\n * Write options for PUT/REMOVE operations\n */\nexport interface WriteOptions {\n /**\n * Write acknowledgment level.\n * @default WriteConcern.MEMORY\n */\n writeConcern?: WriteConcern;\n\n /**\n * Timeout for waiting for acknowledgment (ms).\n * Applies to APPLIED, REPLICATED, PERSISTED levels.\n * @default 5000\n */\n timeout?: number;\n}\n\n/**\n * Result of a write operation\n */\nexport interface WriteResult {\n /** Whether the operation achieved the requested Write Concern level */\n success: boolean;\n\n /** Operation ID */\n opId: string;\n\n /** The Write Concern level actually achieved */\n achievedLevel: WriteConcern;\n\n /** Time taken to achieve the level (ms) */\n latencyMs: number;\n\n /** Error message if success=false */\n error?: string;\n}\n\n/**\n * Internal structure for tracking pending write acknowledgments\n */\nexport interface PendingWrite {\n /** Operation ID */\n opId: string;\n\n /** Target Write Concern level */\n writeConcern: WriteConcern;\n\n /** Timestamp when operation was registered */\n timestamp: number;\n\n /** Timeout duration (ms) */\n timeout: number;\n\n /** Promise resolve callback */\n resolve: (result: WriteResult) => void;\n\n /** Promise reject callback */\n reject: (error: Error) => void;\n\n /** Timeout handle for cleanup */\n timeoutHandle?: ReturnType<typeof setTimeout>;\n\n /** Set of levels that have been achieved */\n achievedLevels: Set<WriteConcern>;\n}\n\n/**\n * Ordered list of Write Concern levels (lowest to highest)\n */\nexport const WRITE_CONCERN_ORDER: readonly WriteConcern[] = [\n WriteConcern.FIRE_AND_FORGET,\n WriteConcern.MEMORY,\n WriteConcern.APPLIED,\n WriteConcern.REPLICATED,\n WriteConcern.PERSISTED,\n] as const;\n\n/**\n * Check if a target Write Concern level is achieved based on achieved levels.\n *\n * @param achieved - Set of achieved Write Concern levels\n * @param target - Target Write Concern level to check\n * @returns true if target level (or higher) is achieved\n */\nexport function isWriteConcernAchieved(\n achieved: Set<WriteConcern>,\n target: WriteConcern\n): boolean {\n const targetIndex = WRITE_CONCERN_ORDER.indexOf(target);\n const achievedIndex = Math.max(\n ...Array.from(achieved).map((l) => WRITE_CONCERN_ORDER.indexOf(l))\n );\n return achievedIndex >= targetIndex;\n}\n\n/**\n * Get the highest achieved Write Concern level from a set of achieved levels.\n *\n * @param achieved - Set of achieved Write Concern levels\n * @returns The highest achieved level\n */\nexport function getHighestWriteConcernLevel(\n achieved: Set<WriteConcern>\n): WriteConcern {\n for (let i = WRITE_CONCERN_ORDER.length - 1; i >= 0; i--) {\n if (achieved.has(WRITE_CONCERN_ORDER[i])) {\n return WRITE_CONCERN_ORDER[i];\n }\n }\n return WriteConcern.FIRE_AND_FORGET;\n}\n"],"mappings":"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","names":["h","h","WriteConcern"]}
|
|
1
|
+
{"version":3,"sources":["../src/HLC.ts","../src/utils/hash.ts","../src/MerkleTree.ts","../src/LWWMap.ts","../src/ORMapMerkle.ts","../src/ORMapMerkleTree.ts","../src/ORMap.ts","../src/serializer.ts","../src/PNCounter.ts","../src/Ringbuffer.ts","../src/EventJournal.ts","../src/EntryProcessor.ts","../src/ConflictResolver.ts","../src/predicate.ts","../src/schemas.ts","../src/types/WriteConcern.ts","../src/types/cluster.ts"],"sourcesContent":["export interface Timestamp {\n millis: number;\n counter: number;\n nodeId: string;\n}\n\nexport class HLC {\n private lastMillis: number;\n private lastCounter: number;\n private readonly nodeId: string;\n\n // Max allowable drift in milliseconds (1 minute)\n private static readonly MAX_DRIFT = 60000;\n\n constructor(nodeId: string) {\n this.nodeId = nodeId;\n this.lastMillis = 0;\n this.lastCounter = 0;\n }\n\n public get getNodeId(): string {\n return this.nodeId;\n }\n\n /**\n * Generates a new unique timestamp for a local event.\n * Ensures monotonicity: always greater than any previously generated or received timestamp.\n */\n public now(): Timestamp {\n const systemTime = Date.now();\n \n // If local physical time catches up to logical time, reset counter\n if (systemTime > this.lastMillis) {\n this.lastMillis = systemTime;\n this.lastCounter = 0;\n } else {\n // Else, just increment the logical counter\n this.lastCounter++;\n }\n\n return {\n millis: this.lastMillis,\n counter: this.lastCounter,\n nodeId: this.nodeId\n };\n }\n\n /**\n * Updates the local clock based on a received remote timestamp.\n * Must be called whenever a message/event is received from another node.\n */\n public update(remote: Timestamp): void {\n const systemTime = Date.now();\n\n // Validate drift (optional but good practice)\n if (remote.millis > systemTime + HLC.MAX_DRIFT) {\n console.warn(`Clock drift detected: Remote time ${remote.millis} is far ahead of local ${systemTime}`);\n // In strict systems we might reject, but in AP systems we usually accept and fast-forward\n }\n\n const maxMillis = Math.max(this.lastMillis, systemTime, remote.millis);\n\n if (maxMillis === this.lastMillis && maxMillis === remote.millis) {\n // Both clocks are on the same millisecond, take max counter\n this.lastCounter = Math.max(this.lastCounter, remote.counter) + 1;\n } else if (maxMillis === this.lastMillis) {\n // Local logical clock is ahead in millis (or same as remote but remote millis < local)\n this.lastCounter++;\n } else if (maxMillis === remote.millis) {\n // Remote clock is ahead, fast-forward local\n this.lastCounter = remote.counter + 1;\n } else {\n // System time is ahead of both\n this.lastCounter = 0;\n }\n\n this.lastMillis = maxMillis;\n }\n\n /**\n * Compares two timestamps.\n * Returns -1 if a < b, 1 if a > b, 0 if equal.\n */\n public static compare(a: Timestamp, b: Timestamp): number {\n if (a.millis !== b.millis) {\n return a.millis - b.millis;\n }\n if (a.counter !== b.counter) {\n return a.counter - b.counter;\n }\n return a.nodeId.localeCompare(b.nodeId);\n }\n\n /**\n * Serializes timestamp to a string representation (e.g., for storage/network).\n * Format: \"<millis>:<counter>:<nodeId>\"\n */\n public static toString(ts: Timestamp): string {\n return `${ts.millis}:${ts.counter}:${ts.nodeId}`;\n }\n\n /**\n * Parses a string representation back to a Timestamp object.\n */\n public static parse(str: string): Timestamp {\n const parts = str.split(':');\n if (parts.length !== 3) {\n throw new Error(`Invalid timestamp format: ${str}`);\n }\n return {\n millis: parseInt(parts[0], 10),\n counter: parseInt(parts[1], 10),\n nodeId: parts[2]\n };\n }\n}\n","/**\n * Hash utilities for TopGun\n *\n * Uses native xxHash64 when available (via @topgunbuild/native),\n * falls back to FNV-1a for JS-only environments.\n *\n * Phase 3.05: Native Hash Integration\n */\n\n// Try to load native hash module\nlet nativeHash: {\n hashString: (str: string) => number;\n isNativeHashAvailable: () => boolean;\n} | null = null;\n\nlet nativeLoadAttempted = false;\n\nfunction tryLoadNative(): void {\n if (nativeLoadAttempted) return;\n nativeLoadAttempted = true;\n\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n nativeHash = require('@topgunbuild/native');\n } catch {\n // Native module not available, will use FNV-1a fallback\n }\n}\n\n/**\n * FNV-1a Hash implementation for strings.\n * Fast, non-cryptographic, synchronous.\n * Used as fallback when native module is unavailable.\n */\nfunction fnv1aHash(str: string): number {\n let hash = 0x811c9dc5;\n for (let i = 0; i < str.length; i++) {\n hash ^= str.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return hash >>> 0; // Ensure positive 32-bit integer\n}\n\n/**\n * Hash a string to a 32-bit unsigned integer.\n *\n * Uses native xxHash64 (truncated to 32 bits) when available,\n * otherwise falls back to FNV-1a.\n *\n * @param str - String to hash\n * @returns 32-bit unsigned integer hash\n */\nexport function hashString(str: string): number {\n tryLoadNative();\n\n if (nativeHash && nativeHash.isNativeHashAvailable()) {\n return nativeHash.hashString(str);\n }\n\n return fnv1aHash(str);\n}\n\n/**\n * Combines multiple hash numbers into one order-independent hash.\n * Used for combining bucket hashes in Merkle trees.\n *\n * Uses simple sum (with overflow handling) for order-independence.\n *\n * @param hashes - Array of hash values to combine\n * @returns Combined hash as 32-bit unsigned integer\n */\nexport function combineHashes(hashes: number[]): number {\n let result = 0;\n for (const h of hashes) {\n result = (result + h) | 0; // Simple sum with overflow\n }\n return result >>> 0;\n}\n\n/**\n * Check if native hash module is being used.\n * Useful for diagnostics and testing.\n */\nexport function isUsingNativeHash(): boolean {\n tryLoadNative();\n return nativeHash?.isNativeHashAvailable() === true;\n}\n\n/**\n * Force use of FNV-1a hash (for testing/compatibility).\n * After calling this, hashString will always use FNV-1a.\n */\nexport function disableNativeHash(): void {\n nativeHash = null;\n nativeLoadAttempted = true;\n}\n\n/**\n * Re-enable native hash loading (for testing).\n * Resets the load state so native module can be loaded again.\n */\nexport function resetNativeHash(): void {\n nativeHash = null;\n nativeLoadAttempted = false;\n}\n","import { LWWRecord } from './LWWMap';\nimport { hashString } from './utils/hash';\n\nexport interface MerkleNode {\n hash: number;\n children?: { [key: string]: MerkleNode }; // Keyed by bucket index (hex char)\n entries?: Map<string, number>; // Leaf node: Key -> ContentHash\n}\n\n/**\n * A specific implementation of Merkle Tree for syncing LWW-Maps.\n * It uses a Prefix Trie structure based on the hash of the Record Key.\n * \n * Structure:\n * - Level 0: Root\n * - Level 1..N: Buckets based on hex digits of Key Hash.\n * \n * This allows us to quickly identify which \"bucket\" of keys is out of sync.\n */\nexport class MerkleTree {\n private root: MerkleNode;\n private readonly depth: number;\n\n constructor(records: Map<string, LWWRecord<any>> = new Map(), depth: number = 3) {\n this.depth = depth;\n this.root = { hash: 0, children: {} };\n // Build initial tree\n for (const [key, record] of records) {\n this.update(key, record);\n }\n }\n\n /**\n * Incrementally updates the Merkle Tree with a single record.\n * @param key The key of the record\n * @param record The record (value + timestamp)\n */\n public update(key: string, record: LWWRecord<any>) {\n const itemHash = hashString(`${key}:${record.timestamp.millis}:${record.timestamp.counter}:${record.timestamp.nodeId}`);\n // We use the hash of the KEY for routing, so the record stays in the same bucket\n // regardless of timestamp changes.\n const pathHash = hashString(key).toString(16).padStart(8, '0'); \n \n this.updateNode(this.root, key, itemHash, pathHash, 0);\n }\n\n /**\n * Removes a key from the Merkle Tree.\n * Necessary for Garbage Collection of tombstones.\n */\n public remove(key: string) {\n const pathHash = hashString(key).toString(16).padStart(8, '0');\n this.removeNode(this.root, key, pathHash, 0);\n }\n\n private removeNode(node: MerkleNode, key: string, pathHash: string, level: number): number {\n // Leaf Node Logic\n if (level >= this.depth) {\n if (node.entries) {\n node.entries.delete(key);\n \n // Recalculate leaf hash\n let h = 0;\n for (const val of node.entries.values()) {\n h = (h + val) | 0;\n }\n node.hash = h >>> 0;\n }\n return node.hash;\n }\n\n // Intermediate Node Logic\n const bucketChar = pathHash[level];\n if (node.children && node.children[bucketChar]) {\n const childHash = this.removeNode(node.children[bucketChar], key, pathHash, level + 1);\n \n // Optimization: if child is empty/zero, we might want to remove it, but for now just recalc.\n }\n \n // Recalculate this node's hash from children\n let h = 0;\n if (node.children) {\n for (const child of Object.values(node.children)) {\n h = (h + child.hash) | 0;\n }\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n private updateNode(node: MerkleNode, key: string, itemHash: number, pathHash: string, level: number): number {\n // Leaf Node Logic\n if (level >= this.depth) {\n if (!node.entries) node.entries = new Map();\n node.entries.set(key, itemHash);\n \n // Recalculate leaf hash (Sum of item hashes)\n let h = 0;\n for (const val of node.entries.values()) {\n h = (h + val) | 0;\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n // Intermediate Node Logic\n const bucketChar = pathHash[level];\n if (!node.children) node.children = {};\n \n if (!node.children[bucketChar]) {\n node.children[bucketChar] = { hash: 0 };\n }\n \n this.updateNode(node.children[bucketChar], key, itemHash, pathHash, level + 1);\n \n // Recalculate this node's hash from children\n let h = 0;\n for (const child of Object.values(node.children)) {\n h = (h + child.hash) | 0;\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n public getRootHash(): number {\n return this.root.hash;\n }\n\n public getNode(path: string): MerkleNode | undefined {\n let current = this.root;\n for (const char of path) {\n if (!current.children || !current.children[char]) {\n return undefined;\n }\n current = current.children[char];\n }\n return current;\n }\n\n /**\n * Returns the hashes of the children at the given path.\n * Used by the client/server to compare buckets.\n */\n public getBuckets(path: string): Record<string, number> {\n const node = this.getNode(path);\n if (!node || !node.children) return {};\n \n const result: Record<string, number> = {};\n for (const [key, child] of Object.entries(node.children)) {\n result[key] = child.hash;\n }\n return result;\n }\n\n /**\n * For a leaf node (bucket), returns the actual keys it contains.\n * Used to request specific keys when a bucket differs.\n */\n public getKeysInBucket(path: string): string[] {\n const node = this.getNode(path);\n if (!node || !node.entries) return [];\n return Array.from(node.entries.keys());\n }\n}\n","import { HLC, Timestamp } from './HLC';\nimport { MerkleTree } from './MerkleTree';\n\n/**\n * A record in the LWW-Map.\n * Can represent a value or a deletion (tombstone).\n */\nexport interface LWWRecord<V> {\n value: V | null;\n timestamp: Timestamp;\n ttlMs?: number;\n}\n\n/**\n * Last-Write-Wins Map Implementation.\n * This structure guarantees convergence by always keeping the entry with the highest timestamp.\n */\nexport class LWWMap<K, V> {\n private data: Map<K, LWWRecord<V>>;\n private readonly hlc: HLC;\n private listeners: Array<() => void> = [];\n private merkleTree: MerkleTree;\n\n constructor(hlc: HLC) {\n this.hlc = hlc;\n this.data = new Map();\n this.merkleTree = new MerkleTree();\n }\n\n public onChange(callback: () => void): () => void {\n this.listeners.push(callback);\n return () => {\n this.listeners = this.listeners.filter(cb => cb !== callback);\n };\n }\n\n private notify(): void {\n this.listeners.forEach(cb => cb());\n }\n\n public getMerkleTree(): MerkleTree {\n return this.merkleTree;\n }\n\n public get size(): number {\n return this.data.size;\n }\n\n /**\n * Sets a value for a key.\n * Generates a new timestamp using the local HLC.\n */\n public set(key: K, value: V, ttlMs?: number): LWWRecord<V> {\n const timestamp = this.hlc.now();\n const record: LWWRecord<V> = { value, timestamp };\n \n if (ttlMs !== undefined) {\n if (typeof ttlMs !== 'number' || ttlMs <= 0 || !Number.isFinite(ttlMs)) {\n // We could throw, but to be resilient we might just ignore invalid TTL or log warning.\n // Given this is core lib, throwing is safer to alert dev.\n throw new Error('TTL must be a positive finite number');\n }\n record.ttlMs = ttlMs;\n }\n \n // We assume K is string for MerkleTree compatibility in this system\n // If K is not string, we might need to stringify it.\n // The project seems to use string keys for maps.\n this.data.set(key, record);\n this.merkleTree.update(String(key), record);\n \n this.notify();\n return record;\n }\n\n /**\n * Retrieves the value for a key.\n * Returns undefined if key doesn't exist, is a tombstone, or is expired.\n */\n public get(key: K): V | undefined {\n const record = this.data.get(key);\n if (!record || record.value === null) {\n return undefined;\n }\n\n // Check for expiration\n if (record.ttlMs) {\n const now = Date.now();\n if (record.timestamp.millis + record.ttlMs < now) {\n return undefined;\n }\n }\n\n return record.value;\n }\n\n /**\n * Returns the full record (including timestamp).\n * Useful for synchronization.\n */\n public getRecord(key: K): LWWRecord<V> | undefined {\n return this.data.get(key);\n }\n\n /**\n * Removes a key (creates a tombstone).\n */\n public remove(key: K): LWWRecord<V> {\n const timestamp = this.hlc.now();\n const tombstone: LWWRecord<V> = { value: null, timestamp };\n \n this.data.set(key, tombstone);\n this.merkleTree.update(String(key), tombstone);\n \n this.notify();\n return tombstone;\n }\n\n /**\n * Merges a record from a remote source.\n * Returns true if the local state was updated.\n */\n public merge(key: K, remoteRecord: LWWRecord<V>): boolean {\n // Update our clock to ensure causality for future events\n this.hlc.update(remoteRecord.timestamp);\n\n const localRecord = this.data.get(key);\n\n // LWW Logic:\n // 1. If no local record, accept remote.\n // 2. If remote is strictly greater than local, accept remote.\n // 3. If equal, we can arbitrarily choose (e.g. by NodeID) to ensure convergence, \n // but HLC.compare handles nodeId tie-breaking already.\n \n if (!localRecord || HLC.compare(remoteRecord.timestamp, localRecord.timestamp) > 0) {\n this.data.set(key, remoteRecord);\n this.merkleTree.update(String(key), remoteRecord);\n \n this.notify();\n return true;\n }\n\n return false;\n }\n\n /**\n * Garbage Collection: Prunes tombstones older than the specified timestamp.\n * Only removes records that are tombstones (deleted) AND older than the threshold.\n * \n * @param olderThan The timestamp threshold. Tombstones older than this will be removed.\n * @returns The number of tombstones removed.\n */\n public prune(olderThan: Timestamp): K[] {\n const removedKeys: K[] = [];\n \n for (const [key, record] of this.data.entries()) {\n // Only prune tombstones (value === null)\n if (record.value === null) {\n // Check if timestamp is strictly older than the threshold\n // HLC.compare(a, b) returns < 0 if a < b\n if (HLC.compare(record.timestamp, olderThan) < 0) {\n this.data.delete(key);\n this.merkleTree.remove(String(key));\n removedKeys.push(key);\n }\n }\n }\n\n if (removedKeys.length > 0) {\n this.notify();\n }\n\n return removedKeys;\n }\n\n /**\n * Clears all data and tombstones.\n * Resets the MerkleTree.\n */\n public clear(): void {\n this.data.clear();\n this.merkleTree = new MerkleTree();\n this.notify();\n }\n\n /**\n * Returns an iterator over all non-deleted entries.\n */\n public entries(): IterableIterator<[K, V]> {\n const iterator = this.data.entries();\n const now = Date.now();\n \n return {\n [Symbol.iterator]() { return this; },\n next: () => {\n let result = iterator.next();\n while (!result.done) {\n const [key, record] = result.value;\n if (record.value !== null) {\n // Check TTL\n if (record.ttlMs && record.timestamp.millis + record.ttlMs < now) {\n result = iterator.next();\n continue;\n }\n return { value: [key, record.value], done: false };\n }\n result = iterator.next();\n }\n return { value: undefined, done: true };\n }\n };\n }\n\n /**\n * Returns all keys (including tombstones).\n */\n public allKeys(): IterableIterator<K> {\n return this.data.keys();\n }\n}\n","import { ORMapRecord } from './ORMap';\nimport { Timestamp } from './HLC';\nimport { hashString } from './utils/hash';\n\n/**\n * Convert Timestamp to deterministic string for hashing.\n * Format: millis:counter:nodeId\n */\nexport function timestampToString(ts: Timestamp): string {\n return `${ts.millis}:${ts.counter}:${ts.nodeId}`;\n}\n\n/**\n * Stringify a value in a deterministic way for hashing.\n */\nfunction stringifyValue(value: unknown): string {\n if (value === null || value === undefined) {\n return String(value);\n }\n if (typeof value === 'object') {\n // Sort object keys for deterministic JSON\n return JSON.stringify(value, Object.keys(value as Record<string, unknown>).sort());\n }\n return String(value);\n}\n\n/**\n * Hash an ORMap entry (key + all its records).\n * Must be deterministic regardless of insertion order.\n *\n * @param key The key of the entry\n * @param records Map of tag -> record for this key\n * @returns Hash as a number (FNV-1a hash)\n */\nexport function hashORMapEntry<V>(\n key: string,\n records: Map<string, ORMapRecord<V>>\n): number {\n // Sort records by tag for deterministic ordering\n const sortedTags = Array.from(records.keys()).sort();\n\n // Build deterministic string representation\n const parts: string[] = [`key:${key}`];\n\n for (const tag of sortedTags) {\n const record = records.get(tag)!;\n // Include tag, value (JSON-stringified), timestamp, and ttl if present\n const valuePart = stringifyValue(record.value);\n\n let recordStr = `${tag}:${valuePart}:${timestampToString(record.timestamp)}`;\n if (record.ttlMs !== undefined) {\n recordStr += `:ttl=${record.ttlMs}`;\n }\n parts.push(recordStr);\n }\n\n return hashString(parts.join('|'));\n}\n\n/**\n * Hash a single ORMapRecord for comparison.\n * Used when comparing individual records during merge.\n */\nexport function hashORMapRecord<V>(record: ORMapRecord<V>): number {\n const valuePart = stringifyValue(record.value);\n\n let str = `${record.tag}:${valuePart}:${timestampToString(record.timestamp)}`;\n if (record.ttlMs !== undefined) {\n str += `:ttl=${record.ttlMs}`;\n }\n\n return hashString(str);\n}\n\n/**\n * Compare two timestamps.\n * Returns:\n * < 0 if a < b\n * > 0 if a > b\n * = 0 if a == b\n */\nexport function compareTimestamps(a: Timestamp, b: Timestamp): number {\n if (a.millis !== b.millis) {\n return a.millis - b.millis;\n }\n if (a.counter !== b.counter) {\n return a.counter - b.counter;\n }\n return a.nodeId.localeCompare(b.nodeId);\n}\n","import { ORMap, ORMapRecord } from './ORMap';\nimport { hashString, combineHashes } from './utils/hash';\nimport { hashORMapEntry } from './ORMapMerkle';\n\n/**\n * Merkle Node for ORMap.\n * Uses a prefix trie structure based on key hash (similar to LWWMap MerkleTree).\n */\nexport interface ORMapMerkleNode {\n hash: number;\n children?: { [key: string]: ORMapMerkleNode }; // Keyed by bucket index (hex char)\n entries?: Map<string, number>; // Leaf node: Key -> ContentHash\n}\n\n/**\n * A Merkle Tree implementation specifically for ORMap synchronization.\n * Uses a Prefix Trie structure based on the hash of the Record Key.\n *\n * Structure:\n * - Level 0: Root\n * - Level 1..N: Buckets based on hex digits of Key Hash.\n *\n * Key difference from LWWMap MerkleTree:\n * - Each key can have multiple records (tags), so the entry hash includes all records for that key.\n */\nexport class ORMapMerkleTree {\n private root: ORMapMerkleNode;\n private readonly depth: number;\n\n constructor(depth: number = 3) {\n this.depth = depth;\n this.root = { hash: 0, children: {} };\n }\n\n /**\n * Update tree from ORMap data.\n * Rebuilds hashes for all entries in the map.\n */\n updateFromORMap<K, V>(map: ORMap<K, V>): void {\n // Clear and rebuild\n this.root = { hash: 0, children: {} };\n\n // Access internal items through available methods\n // We need to iterate over all keys and get their records\n const snapshot = map.getSnapshot();\n\n for (const [key, records] of snapshot.items) {\n if (records.size > 0) {\n const keyStr = String(key);\n const entryHash = hashORMapEntry(keyStr, records);\n const pathHash = hashString(keyStr).toString(16).padStart(8, '0');\n this.updateNode(this.root, keyStr, entryHash, pathHash, 0);\n }\n }\n }\n\n /**\n * Incrementally update a single key's hash.\n * Call this when records for a key change.\n */\n update<V>(key: string, records: Map<string, ORMapRecord<V>>): void {\n const pathHash = hashString(key).toString(16).padStart(8, '0');\n\n if (records.size === 0) {\n // Key has no records, remove from tree\n this.removeNode(this.root, key, pathHash, 0);\n } else {\n const entryHash = hashORMapEntry(key, records);\n this.updateNode(this.root, key, entryHash, pathHash, 0);\n }\n }\n\n /**\n * Remove a key from the tree.\n * Called when all records for a key are removed.\n */\n remove(key: string): void {\n const pathHash = hashString(key).toString(16).padStart(8, '0');\n this.removeNode(this.root, key, pathHash, 0);\n }\n\n private updateNode(\n node: ORMapMerkleNode,\n key: string,\n entryHash: number,\n pathHash: string,\n level: number\n ): number {\n // Leaf Node Logic\n if (level >= this.depth) {\n if (!node.entries) node.entries = new Map();\n node.entries.set(key, entryHash);\n\n // Recalculate leaf hash (Sum of entry hashes)\n let h = 0;\n for (const val of node.entries.values()) {\n h = (h + val) | 0;\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n // Intermediate Node Logic\n const bucketChar = pathHash[level];\n if (!node.children) node.children = {};\n\n if (!node.children[bucketChar]) {\n node.children[bucketChar] = { hash: 0 };\n }\n\n this.updateNode(node.children[bucketChar], key, entryHash, pathHash, level + 1);\n\n // Recalculate this node's hash from children\n let h = 0;\n for (const child of Object.values(node.children)) {\n h = (h + child.hash) | 0;\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n private removeNode(\n node: ORMapMerkleNode,\n key: string,\n pathHash: string,\n level: number\n ): number {\n // Leaf Node Logic\n if (level >= this.depth) {\n if (node.entries) {\n node.entries.delete(key);\n\n // Recalculate leaf hash\n let h = 0;\n for (const val of node.entries.values()) {\n h = (h + val) | 0;\n }\n node.hash = h >>> 0;\n }\n return node.hash;\n }\n\n // Intermediate Node Logic\n const bucketChar = pathHash[level];\n if (node.children && node.children[bucketChar]) {\n this.removeNode(node.children[bucketChar], key, pathHash, level + 1);\n }\n\n // Recalculate this node's hash from children\n let h = 0;\n if (node.children) {\n for (const child of Object.values(node.children)) {\n h = (h + child.hash) | 0;\n }\n }\n node.hash = h >>> 0;\n return node.hash;\n }\n\n /**\n * Get the root hash for quick comparison.\n */\n getRootHash(): number {\n return this.root.hash;\n }\n\n /**\n * Get node at a specific path.\n */\n getNode(path: string): ORMapMerkleNode | undefined {\n let current = this.root;\n for (const char of path) {\n if (!current.children || !current.children[char]) {\n return undefined;\n }\n current = current.children[char];\n }\n return current;\n }\n\n /**\n * Returns the hashes of the children at the given path.\n * Used by the client/server to compare buckets.\n */\n getBuckets(path: string): Record<string, number> {\n const node = this.getNode(path);\n if (!node || !node.children) return {};\n\n const result: Record<string, number> = {};\n for (const [key, child] of Object.entries(node.children)) {\n result[key] = child.hash;\n }\n return result;\n }\n\n /**\n * For a leaf node (bucket), returns the actual keys it contains.\n * Used to request specific keys when a bucket differs.\n */\n getKeysInBucket(path: string): string[] {\n const node = this.getNode(path);\n if (!node || !node.entries) return [];\n return Array.from(node.entries.keys());\n }\n\n /**\n * Find keys that differ between this tree and bucket info from remote.\n * Returns keys that:\n * - Exist locally but have different hash on remote\n * - Exist on remote but not locally\n * - Exist locally but not on remote\n */\n findDiffKeys(path: string, remoteEntries: Map<string, number>): Set<string> {\n const diffKeys = new Set<string>();\n const node = this.getNode(path);\n const localEntries = node?.entries || new Map();\n\n // Keys in local but not remote, or different hash\n for (const [key, hash] of localEntries) {\n const remoteHash = remoteEntries.get(key);\n if (remoteHash === undefined || remoteHash !== hash) {\n diffKeys.add(key);\n }\n }\n\n // Keys in remote but not local\n for (const key of remoteEntries.keys()) {\n if (!localEntries.has(key)) {\n diffKeys.add(key);\n }\n }\n\n return diffKeys;\n }\n\n /**\n * Get all entry hashes at a leaf path.\n * Used when sending bucket details to remote.\n */\n getEntryHashes(path: string): Map<string, number> {\n const node = this.getNode(path);\n return node?.entries || new Map();\n }\n\n /**\n * Check if a path leads to a leaf node.\n */\n isLeaf(path: string): boolean {\n const node = this.getNode(path);\n return node !== undefined && node.entries !== undefined && node.entries.size > 0;\n }\n}\n","import { HLC, Timestamp } from './HLC';\nimport { ORMapMerkleTree } from './ORMapMerkleTree';\nimport { compareTimestamps } from './ORMapMerkle';\n\n/**\n * A record in the OR-Map (Observed-Remove Map).\n * Represents a single value instance with a unique tag.\n */\nexport interface ORMapRecord<V> {\n value: V;\n timestamp: Timestamp;\n tag: string; // Unique identifier (UUID + Timestamp)\n ttlMs?: number;\n}\n\n/**\n * Result of merging records for a key.\n */\nexport interface MergeKeyResult {\n added: number;\n updated: number;\n}\n\n/**\n * Snapshot of ORMap internal state for Merkle Tree synchronization.\n */\nexport interface ORMapSnapshot<K, V> {\n items: Map<K, Map<string, ORMapRecord<V>>>;\n tombstones: Set<string>;\n}\n\n/**\n * OR-Map (Observed-Remove Map) Implementation.\n * \n * Acts as a Multimap where each Key holds a Set of Values.\n * Supports concurrent additions to the same key without data loss.\n * \n * Logic:\n * - Add(K, V): Generates a unique tag. Stores (V, tag) under K.\n * - Remove(K, V): Finds all *currently observed* tags for V under K, and moves them to a Remove Set (Tombstones).\n * - Merge: Union of items minus Union of tombstones.\n */\nexport class ORMap<K, V> {\n // Key -> Map<Tag, Record>\n // Stores active records.\n private items: Map<K, Map<string, ORMapRecord<V>>>;\n\n // Set of removed tags (Tombstones).\n private tombstones: Set<string>;\n\n // Set of expired tags (Local only cache for fast filtering)\n // Note: We don't persist this directly, but rely on filtering.\n // For now, we will just filter on get()\n\n private readonly hlc: HLC;\n\n // Merkle Tree for efficient sync\n private merkleTree: ORMapMerkleTree;\n\n constructor(hlc: HLC) {\n this.hlc = hlc;\n this.items = new Map();\n this.tombstones = new Set();\n this.merkleTree = new ORMapMerkleTree();\n }\n\n private listeners: Array<() => void> = [];\n\n public onChange(callback: () => void): () => void {\n this.listeners.push(callback);\n return () => {\n this.listeners = this.listeners.filter(cb => cb !== callback);\n };\n }\n\n private notify(): void {\n this.listeners.forEach(cb => cb());\n }\n\n public get size(): number {\n return this.items.size;\n }\n\n public get totalRecords(): number {\n let count = 0;\n for (const keyMap of this.items.values()) {\n count += keyMap.size;\n }\n return count;\n }\n\n /**\n * Adds a value to the set associated with the key.\n * Generates a unique tag for this specific addition.\n */\n public add(key: K, value: V, ttlMs?: number): ORMapRecord<V> {\n const timestamp = this.hlc.now();\n // Tag must be unique globally. HLC.toString() provides unique string per node+time.\n const tag = HLC.toString(timestamp);\n\n const record: ORMapRecord<V> = {\n value,\n timestamp,\n tag\n };\n\n if (ttlMs !== undefined) {\n if (typeof ttlMs !== 'number' || ttlMs <= 0 || !Number.isFinite(ttlMs)) {\n throw new Error('TTL must be a positive finite number');\n }\n record.ttlMs = ttlMs;\n }\n\n let keyMap = this.items.get(key);\n if (!keyMap) {\n keyMap = new Map();\n this.items.set(key, keyMap);\n }\n\n keyMap.set(tag, record);\n this.updateMerkleTree(key);\n this.notify();\n return record;\n }\n\n /**\n * Removes a specific value from the set associated with the key.\n * Marks all *currently observed* instances of this value as removed (tombstones).\n * Returns the list of tags that were removed (useful for sync).\n */\n public remove(key: K, value: V): string[] {\n const keyMap = this.items.get(key);\n if (!keyMap) return [];\n\n // Find all tags for this value\n const tagsToRemove: string[] = [];\n\n for (const [tag, record] of keyMap.entries()) {\n // Using strict equality. For objects, this requires the exact instance.\n if (record.value === value) {\n tagsToRemove.push(tag);\n }\n }\n\n for (const tag of tagsToRemove) {\n this.tombstones.add(tag);\n keyMap.delete(tag);\n }\n\n if (keyMap.size === 0) {\n this.items.delete(key);\n }\n\n this.updateMerkleTree(key);\n this.notify();\n return tagsToRemove;\n }\n\n /**\n * Clears all data and tombstones.\n */\n public clear(): void {\n this.items.clear();\n this.tombstones.clear();\n this.merkleTree = new ORMapMerkleTree();\n this.notify();\n }\n\n /**\n * Returns all active values for a key.\n * Filters out expired records.\n */\n public get(key: K): V[] {\n const keyMap = this.items.get(key);\n if (!keyMap) return [];\n\n const values: V[] = [];\n const now = Date.now();\n\n for (const [tag, record] of keyMap.entries()) {\n if (!this.tombstones.has(tag)) {\n // Check expiration\n if (record.ttlMs && record.timestamp.millis + record.ttlMs < now) {\n continue;\n }\n values.push(record.value);\n }\n }\n return values;\n }\n\n /**\n * Returns all active records for a key.\n * Useful for persistence and sync.\n * Filters out expired records.\n */\n public getRecords(key: K): ORMapRecord<V>[] {\n const keyMap = this.items.get(key);\n if (!keyMap) return [];\n\n const records: ORMapRecord<V>[] = [];\n const now = Date.now();\n\n for (const [tag, record] of keyMap.entries()) {\n if (!this.tombstones.has(tag)) {\n // Check expiration\n if (record.ttlMs && record.timestamp.millis + record.ttlMs < now) {\n continue;\n }\n records.push(record);\n }\n }\n return records;\n }\n\n /**\n * Returns all tombstone tags.\n */\n public getTombstones(): string[] {\n return Array.from(this.tombstones);\n }\n\n /**\n * Applies a record from a remote source (Sync).\n * Returns true if the record was applied (not tombstoned).\n */\n public apply(key: K, record: ORMapRecord<V>): boolean {\n if (this.tombstones.has(record.tag)) return false;\n\n let keyMap = this.items.get(key);\n if (!keyMap) {\n keyMap = new Map();\n this.items.set(key, keyMap);\n }\n keyMap.set(record.tag, record);\n this.hlc.update(record.timestamp);\n this.updateMerkleTree(key);\n this.notify();\n return true;\n }\n\n /**\n * Applies a tombstone (deletion) from a remote source.\n */\n public applyTombstone(tag: string): void {\n this.tombstones.add(tag);\n // Cleanup active items if present\n for (const [key, keyMap] of this.items) {\n if (keyMap.has(tag)) {\n keyMap.delete(tag);\n if (keyMap.size === 0) this.items.delete(key);\n this.updateMerkleTree(key);\n // We found it, so we can stop searching (tag is unique globally)\n break;\n }\n }\n this.notify();\n }\n\n /**\n * Merges state from another ORMap.\n * - Adds all new tombstones from 'other'.\n * - Adds all new items from 'other' that are not in tombstones.\n * - Updates HLC with observed timestamps.\n */\n public merge(other: ORMap<K, V>): void {\n const changedKeys = new Set<K>();\n\n // 1. Merge tombstones\n for (const tag of other.tombstones) {\n this.tombstones.add(tag);\n }\n\n // 2. Merge items\n for (const [key, otherKeyMap] of other.items) {\n let localKeyMap = this.items.get(key);\n if (!localKeyMap) {\n localKeyMap = new Map();\n this.items.set(key, localKeyMap);\n }\n\n for (const [tag, record] of otherKeyMap) {\n // Only accept if not deleted\n if (!this.tombstones.has(tag)) {\n if (!localKeyMap.has(tag)) {\n localKeyMap.set(tag, record);\n changedKeys.add(key);\n }\n // Always update causality\n this.hlc.update(record.timestamp);\n }\n }\n }\n\n // 3. Cleanup: Remove any local items that are now in the merged tombstones\n for (const [key, localKeyMap] of this.items) {\n for (const tag of localKeyMap.keys()) {\n if (this.tombstones.has(tag)) {\n localKeyMap.delete(tag);\n changedKeys.add(key);\n }\n }\n if (localKeyMap.size === 0) {\n this.items.delete(key);\n }\n }\n\n // Update Merkle Tree for changed keys\n for (const key of changedKeys) {\n this.updateMerkleTree(key);\n }\n\n this.notify();\n }\n\n /**\n * Garbage Collection: Prunes tombstones older than the specified timestamp.\n */\n public prune(olderThan: Timestamp): string[] {\n const removedTags: string[] = [];\n\n for (const tag of this.tombstones) {\n try {\n const timestamp = HLC.parse(tag);\n if (HLC.compare(timestamp, olderThan) < 0) {\n this.tombstones.delete(tag);\n removedTags.push(tag);\n }\n } catch (e) {\n // Ignore invalid tags\n }\n }\n\n return removedTags;\n }\n\n // ============ Merkle Sync Methods ============\n\n /**\n * Get the Merkle Tree for this ORMap.\n * Used for efficient synchronization.\n */\n public getMerkleTree(): ORMapMerkleTree {\n return this.merkleTree;\n }\n\n /**\n * Get a snapshot of internal state for Merkle Tree synchronization.\n * Returns references to internal structures - do not modify!\n */\n public getSnapshot(): ORMapSnapshot<K, V> {\n return {\n items: this.items,\n tombstones: this.tombstones\n };\n }\n\n /**\n * Get all keys in this ORMap.\n */\n public allKeys(): K[] {\n return Array.from(this.items.keys());\n }\n\n /**\n * Get the internal records map for a key.\n * Returns Map<tag, record> or undefined if key doesn't exist.\n * Used for Merkle sync.\n */\n public getRecordsMap(key: K): Map<string, ORMapRecord<V>> | undefined {\n return this.items.get(key);\n }\n\n /**\n * Merge remote records for a specific key into local state.\n * Implements Observed-Remove CRDT semantics.\n * Used during Merkle Tree synchronization.\n *\n * @param key The key to merge\n * @param remoteRecords Array of records from remote\n * @param remoteTombstones Array of tombstone tags from remote\n * @returns Result with count of added and updated records\n */\n public mergeKey(\n key: K,\n remoteRecords: ORMapRecord<V>[],\n remoteTombstones: string[] = []\n ): MergeKeyResult {\n let added = 0;\n let updated = 0;\n\n // First apply remote tombstones\n for (const tag of remoteTombstones) {\n if (!this.tombstones.has(tag)) {\n this.tombstones.add(tag);\n }\n }\n\n // Get or create local key map\n let localKeyMap = this.items.get(key);\n if (!localKeyMap) {\n localKeyMap = new Map();\n this.items.set(key, localKeyMap);\n }\n\n // Remove any local records that are now tombstoned\n for (const tag of localKeyMap.keys()) {\n if (this.tombstones.has(tag)) {\n localKeyMap.delete(tag);\n }\n }\n\n // Merge remote records\n for (const remoteRecord of remoteRecords) {\n // Skip if tombstoned\n if (this.tombstones.has(remoteRecord.tag)) {\n continue;\n }\n\n const localRecord = localKeyMap.get(remoteRecord.tag);\n\n if (!localRecord) {\n // New record - add it\n localKeyMap.set(remoteRecord.tag, remoteRecord);\n added++;\n } else if (compareTimestamps(remoteRecord.timestamp, localRecord.timestamp) > 0) {\n // Remote is newer - update\n localKeyMap.set(remoteRecord.tag, remoteRecord);\n updated++;\n }\n // Else: local is newer or equal, keep local\n\n // Always update causality\n this.hlc.update(remoteRecord.timestamp);\n }\n\n // Cleanup empty key map\n if (localKeyMap.size === 0) {\n this.items.delete(key);\n }\n\n // Update Merkle Tree\n this.updateMerkleTree(key);\n\n if (added > 0 || updated > 0) {\n this.notify();\n }\n\n return { added, updated };\n }\n\n /**\n * Check if a tag is tombstoned.\n */\n public isTombstoned(tag: string): boolean {\n return this.tombstones.has(tag);\n }\n\n /**\n * Update the Merkle Tree for a specific key.\n * Called internally after any modification.\n */\n private updateMerkleTree(key: K): void {\n const keyStr = String(key);\n const keyMap = this.items.get(key);\n\n if (!keyMap || keyMap.size === 0) {\n this.merkleTree.remove(keyStr);\n } else {\n this.merkleTree.update(keyStr, keyMap);\n }\n }\n}\n","import { pack, unpack } from 'msgpackr';\n\n/**\n * Serializes a JavaScript object to MessagePack binary format.\n * Uses msgpackr for 2-5x faster serialization compared to @msgpack/msgpack.\n * @param data The data to serialize.\n * @returns A Uint8Array containing the serialized data.\n */\nexport function serialize(data: unknown): Uint8Array {\n return pack(data);\n}\n\n/**\n * Deserializes MessagePack binary data to a JavaScript object.\n * Uses msgpackr for 2-5x faster deserialization compared to @msgpack/msgpack.\n * @param data The binary data to deserialize (Uint8Array or ArrayBuffer).\n * @returns The deserialized object.\n */\nexport function deserialize<T = unknown>(data: Uint8Array | ArrayBuffer): T {\n // msgpackr unpack accepts Uint8Array, Buffer, ArrayBuffer\n const buffer = data instanceof ArrayBuffer ? new Uint8Array(data) : data;\n return unpack(buffer) as T;\n}\n\n","import { serialize, deserialize } from './serializer';\n\n/**\n * State of a PN Counter CRDT.\n * Tracks positive and negative increments per node for convergence.\n */\nexport interface PNCounterState {\n /** Positive increments per node */\n positive: Map<string, number>;\n /** Negative increments per node */\n negative: Map<string, number>;\n}\n\n/**\n * Serializable form of PNCounterState for network/storage.\n */\nexport interface PNCounterStateObject {\n /** Positive increments per node as object */\n p: Record<string, number>;\n /** Negative increments per node as object */\n n: Record<string, number>;\n}\n\n/**\n * Configuration for creating a PN Counter.\n */\nexport interface PNCounterConfig {\n /** Unique node identifier for this counter instance */\n nodeId: string;\n /** Initial state to restore from */\n initialState?: PNCounterState;\n}\n\n/**\n * Interface for PN Counter CRDT.\n */\nexport interface PNCounter {\n /** Get current value */\n get(): number;\n\n /** Increment by 1, return new value */\n increment(): number;\n\n /** Decrement by 1, return new value */\n decrement(): number;\n\n /** Add delta (positive or negative), return new value */\n addAndGet(delta: number): number;\n\n /** Get state for sync */\n getState(): PNCounterState;\n\n /** Merge remote state */\n merge(remote: PNCounterState): void;\n\n /** Subscribe to value changes */\n subscribe(listener: (value: number) => void): () => void;\n}\n\n/**\n * Positive-Negative Counter CRDT implementation.\n *\n * A PN Counter is a CRDT that supports increment and decrement operations\n * on any node, works offline, and guarantees convergence without coordination.\n *\n * How it works:\n * - Tracks positive increments per node in a G-Counter\n * - Tracks negative increments per node in another G-Counter\n * - Value = sum(positive) - sum(negative)\n * - Merge takes max for each node in both counters\n *\n * @example\n * ```typescript\n * const counter = new PNCounterImpl({ nodeId: 'node-1' });\n * counter.increment(); // 1\n * counter.increment(); // 2\n * counter.decrement(); // 1\n * counter.addAndGet(5); // 6\n * ```\n */\nexport class PNCounterImpl implements PNCounter {\n private readonly nodeId: string;\n private state: PNCounterState;\n private listeners: Set<(value: number) => void> = new Set();\n\n constructor(config: PNCounterConfig) {\n this.nodeId = config.nodeId;\n this.state = config.initialState ?? {\n positive: new Map(),\n negative: new Map(),\n };\n }\n\n /**\n * Get the current counter value.\n * Value = sum(positive) - sum(negative)\n */\n get(): number {\n let sum = 0;\n for (const v of this.state.positive.values()) sum += v;\n for (const v of this.state.negative.values()) sum -= v;\n return sum;\n }\n\n /**\n * Increment by 1 and return the new value.\n */\n increment(): number {\n return this.addAndGet(1);\n }\n\n /**\n * Decrement by 1 and return the new value.\n */\n decrement(): number {\n return this.addAndGet(-1);\n }\n\n /**\n * Add a delta (positive or negative) and return the new value.\n * @param delta The amount to add (can be negative)\n */\n addAndGet(delta: number): number {\n if (delta === 0) return this.get();\n\n if (delta > 0) {\n const current = this.state.positive.get(this.nodeId) ?? 0;\n this.state.positive.set(this.nodeId, current + delta);\n } else {\n const current = this.state.negative.get(this.nodeId) ?? 0;\n this.state.negative.set(this.nodeId, current + Math.abs(delta));\n }\n\n const newValue = this.get();\n this.notifyListeners(newValue);\n return newValue;\n }\n\n /**\n * Get a copy of the current state for synchronization.\n */\n getState(): PNCounterState {\n return {\n positive: new Map(this.state.positive),\n negative: new Map(this.state.negative),\n };\n }\n\n /**\n * Merge remote state into this counter.\n * Takes the maximum value for each node in both positive and negative counters.\n * This operation is commutative, associative, and idempotent (CRDT properties).\n *\n * @param remote The remote state to merge\n */\n merge(remote: PNCounterState): void {\n let changed = false;\n\n // Merge positive: take max for each node\n for (const [nodeId, value] of remote.positive) {\n const current = this.state.positive.get(nodeId) ?? 0;\n if (value > current) {\n this.state.positive.set(nodeId, value);\n changed = true;\n }\n }\n\n // Merge negative: take max for each node\n for (const [nodeId, value] of remote.negative) {\n const current = this.state.negative.get(nodeId) ?? 0;\n if (value > current) {\n this.state.negative.set(nodeId, value);\n changed = true;\n }\n }\n\n if (changed) {\n this.notifyListeners(this.get());\n }\n }\n\n /**\n * Subscribe to value changes.\n * The listener is immediately called with the current value.\n *\n * @param listener Callback function receiving the new value\n * @returns Unsubscribe function\n */\n subscribe(listener: (value: number) => void): () => void {\n this.listeners.add(listener);\n // Immediately notify with current value\n listener(this.get());\n return () => this.listeners.delete(listener);\n }\n\n private notifyListeners(value: number): void {\n for (const listener of this.listeners) {\n try {\n listener(value);\n } catch (e) {\n // Silently catch listener errors to prevent breaking other listeners\n }\n }\n }\n\n /**\n * Get the node ID of this counter instance.\n */\n getNodeId(): string {\n return this.nodeId;\n }\n\n // ============================================\n // Serialization\n // ============================================\n\n /**\n * Serialize state to binary format (msgpack).\n */\n static serialize(state: PNCounterState): Uint8Array {\n const obj: PNCounterStateObject = {\n p: Object.fromEntries(state.positive),\n n: Object.fromEntries(state.negative),\n };\n return serialize(obj);\n }\n\n /**\n * Deserialize binary data to state.\n */\n static deserialize(data: Uint8Array): PNCounterState {\n const obj = deserialize<PNCounterStateObject>(data);\n return {\n positive: new Map(Object.entries(obj.p)),\n negative: new Map(Object.entries(obj.n)),\n };\n }\n\n /**\n * Convert state to plain object (for JSON/network).\n */\n static stateToObject(state: PNCounterState): PNCounterStateObject {\n return {\n p: Object.fromEntries(state.positive),\n n: Object.fromEntries(state.negative),\n };\n }\n\n /**\n * Convert plain object to state.\n */\n static objectToState(obj: PNCounterStateObject): PNCounterState {\n return {\n positive: new Map(Object.entries(obj.p)),\n negative: new Map(Object.entries(obj.n)),\n };\n }\n}\n","/**\n * Fixed-size circular buffer with sequence numbers.\n * Older entries are overwritten when capacity is reached.\n *\n * @template T - Type of items stored in the buffer\n */\nexport class Ringbuffer<T> {\n private buffer: (T | undefined)[];\n private readonly _capacity: number;\n private headSequence: bigint = 0n; // Oldest available sequence\n private tailSequence: bigint = 0n; // Next sequence to write\n\n constructor(capacity: number) {\n if (capacity < 1) {\n throw new Error('Capacity must be >= 1');\n }\n this._capacity = capacity;\n this.buffer = new Array(capacity);\n }\n\n /**\n * Add item to buffer, returns sequence number.\n */\n add(item: T): bigint {\n const sequence = this.tailSequence;\n const index = Number(sequence % BigInt(this._capacity));\n\n this.buffer[index] = item;\n this.tailSequence++;\n\n // Advance head if we overwrote oldest\n if (this.tailSequence - this.headSequence > this._capacity) {\n this.headSequence = this.tailSequence - BigInt(this._capacity);\n }\n\n return sequence;\n }\n\n /**\n * Read item at sequence.\n * Returns undefined if sequence is out of range.\n */\n read(sequence: bigint): T | undefined {\n if (sequence < this.headSequence || sequence >= this.tailSequence) {\n return undefined;\n }\n const index = Number(sequence % BigInt(this._capacity));\n return this.buffer[index];\n }\n\n /**\n * Read range of items (inclusive).\n * Automatically clamps to available range.\n */\n readRange(startSeq: bigint, endSeq: bigint): T[] {\n const items: T[] = [];\n const actualStart = startSeq < this.headSequence ? this.headSequence : startSeq;\n const actualEnd = endSeq >= this.tailSequence ? this.tailSequence - 1n : endSeq;\n\n for (let seq = actualStart; seq <= actualEnd; seq++) {\n const item = this.read(seq);\n if (item !== undefined) {\n items.push(item);\n }\n }\n\n return items;\n }\n\n /**\n * Read from sequence with limit.\n */\n readFrom(startSeq: bigint, limit: number = 100): T[] {\n const endSeq = startSeq + BigInt(limit) - 1n;\n return this.readRange(startSeq, endSeq);\n }\n\n /**\n * Get the oldest available sequence number.\n */\n getHeadSequence(): bigint {\n return this.headSequence;\n }\n\n /**\n * Get the next sequence number to be written.\n */\n getTailSequence(): bigint {\n return this.tailSequence;\n }\n\n /**\n * Get the number of items currently in the buffer.\n */\n size(): number {\n return Number(this.tailSequence - this.headSequence);\n }\n\n /**\n * Get the maximum capacity of the buffer.\n */\n getCapacity(): number {\n return this._capacity;\n }\n\n /**\n * Clear all items from the buffer.\n */\n clear(): void {\n this.buffer = new Array(this._capacity);\n this.headSequence = 0n;\n this.tailSequence = 0n;\n }\n\n /**\n * Check if a sequence is available in the buffer.\n */\n isAvailable(sequence: bigint): boolean {\n return sequence >= this.headSequence && sequence < this.tailSequence;\n }\n\n /**\n * Get remaining capacity before oldest entries are overwritten.\n */\n remainingCapacity(): number {\n return this._capacity - this.size();\n }\n}\n","import { Ringbuffer } from './Ringbuffer';\nimport type { Timestamp } from './HLC';\n\n/**\n * Type of journal event.\n */\nexport type JournalEventType = 'PUT' | 'UPDATE' | 'DELETE';\n\n/**\n * Single event in the journal.\n */\nexport interface JournalEvent<V = unknown> {\n /** Monotonically increasing sequence number */\n sequence: bigint;\n\n /** Event type */\n type: JournalEventType;\n\n /** Map name */\n mapName: string;\n\n /** Entry key */\n key: string;\n\n /** New value (undefined for DELETE) */\n value?: V;\n\n /** Previous value (for UPDATE and DELETE) */\n previousValue?: V;\n\n /** HLC timestamp */\n timestamp: Timestamp;\n\n /** Node that made the change */\n nodeId: string;\n\n /** Optional metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Input for appending events (without sequence).\n */\nexport type JournalEventInput<V = unknown> = Omit<JournalEvent<V>, 'sequence'>;\n\n/**\n * Event Journal configuration.\n */\nexport interface EventJournalConfig {\n /** Maximum number of events to keep in memory */\n capacity: number;\n\n /** Time-to-live for events (ms), 0 = infinite */\n ttlMs: number;\n\n /** Persist to storage adapter */\n persistent: boolean;\n\n /** Maps to include (empty = all) */\n includeMaps?: string[];\n\n /** Maps to exclude */\n excludeMaps?: string[];\n}\n\n/**\n * Default configuration for Event Journal.\n */\nexport const DEFAULT_EVENT_JOURNAL_CONFIG: EventJournalConfig = {\n capacity: 10000,\n ttlMs: 0, // Infinite\n persistent: true,\n includeMaps: [],\n excludeMaps: [],\n};\n\n/**\n * Event Journal interface.\n */\nexport interface EventJournal {\n /** Append event to journal */\n append<V>(event: JournalEventInput<V>): JournalEvent<V>;\n\n /** Read events from sequence (inclusive) */\n readFrom(sequence: bigint, limit?: number): JournalEvent[];\n\n /** Read events in range */\n readRange(startSeq: bigint, endSeq: bigint): JournalEvent[];\n\n /** Get latest sequence number */\n getLatestSequence(): bigint;\n\n /** Get oldest sequence number (after compaction) */\n getOldestSequence(): bigint;\n\n /** Subscribe to new events */\n subscribe(\n listener: (event: JournalEvent) => void,\n fromSequence?: bigint\n ): () => void;\n\n /** Get capacity info */\n getCapacity(): { used: number; total: number };\n\n /** Force compaction */\n compact(): Promise<void>;\n\n /** Dispose resources */\n dispose(): void;\n}\n\n/**\n * Journal event listener type.\n */\nexport type JournalEventListener = (event: JournalEvent) => void;\n\n/**\n * Event Journal implementation using Ringbuffer.\n * Records all Map changes as an append-only log.\n */\nexport class EventJournalImpl implements EventJournal {\n private readonly config: EventJournalConfig;\n private readonly buffer: Ringbuffer<JournalEvent>;\n private readonly listeners: Set<JournalEventListener> = new Set();\n private ttlTimer?: ReturnType<typeof setInterval>;\n\n constructor(config: Partial<EventJournalConfig> = {}) {\n this.config = { ...DEFAULT_EVENT_JOURNAL_CONFIG, ...config };\n this.buffer = new Ringbuffer(this.config.capacity);\n\n if (this.config.ttlMs > 0) {\n this.startTTLCleanup();\n }\n }\n\n /**\n * Append event to journal.\n * Returns the event with assigned sequence number.\n * Returns event with sequence -1n if map is filtered out.\n */\n append<V>(eventData: JournalEventInput<V>): JournalEvent<V> {\n // Check map filters\n if (!this.shouldCapture(eventData.mapName)) {\n return { ...eventData, sequence: -1n } as JournalEvent<V>;\n }\n\n const event: JournalEvent<V> = {\n ...eventData,\n sequence: 0n, // Will be set by buffer\n };\n\n const sequence = this.buffer.add(event);\n event.sequence = sequence;\n\n // Notify listeners\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch (e) {\n console.error('EventJournal listener error:', e);\n }\n }\n\n return event;\n }\n\n /**\n * Read events from sequence with optional limit.\n */\n readFrom(sequence: bigint, limit: number = 100): JournalEvent[] {\n return this.buffer.readFrom(sequence, limit);\n }\n\n /**\n * Read events in range (inclusive).\n */\n readRange(startSeq: bigint, endSeq: bigint): JournalEvent[] {\n return this.buffer.readRange(startSeq, endSeq);\n }\n\n /**\n * Get latest sequence number.\n * Returns 0n if no events have been added.\n */\n getLatestSequence(): bigint {\n const tail = this.buffer.getTailSequence();\n return tail > 0n ? tail - 1n : 0n;\n }\n\n /**\n * Get oldest available sequence number.\n */\n getOldestSequence(): bigint {\n return this.buffer.getHeadSequence();\n }\n\n /**\n * Subscribe to new events.\n * Optionally replay events from a specific sequence.\n *\n * @param listener Callback for each event\n * @param fromSequence Optional sequence to start replay from\n * @returns Unsubscribe function\n */\n subscribe(\n listener: JournalEventListener,\n fromSequence?: bigint\n ): () => void {\n // Replay events if fromSequence is specified\n if (fromSequence !== undefined) {\n const events = this.readFrom(fromSequence, this.config.capacity);\n for (const event of events) {\n try {\n listener(event);\n } catch (e) {\n console.error('EventJournal replay error:', e);\n }\n }\n }\n\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Get capacity information.\n */\n getCapacity(): { used: number; total: number } {\n return {\n used: this.buffer.size(),\n total: this.buffer.getCapacity(),\n };\n }\n\n /**\n * Force compaction.\n * Note: The ringbuffer handles eviction automatically.\n * This method is provided for explicit cleanup of old events.\n */\n async compact(): Promise<void> {\n // The ringbuffer automatically evicts old entries when full.\n // TTL-based cleanup is handled by the timer.\n // This method can be extended for additional cleanup logic.\n }\n\n /**\n * Check if a map should be captured.\n */\n private shouldCapture(mapName: string): boolean {\n const { includeMaps, excludeMaps } = this.config;\n\n if (excludeMaps && excludeMaps.includes(mapName)) {\n return false;\n }\n\n if (includeMaps && includeMaps.length > 0) {\n return includeMaps.includes(mapName);\n }\n\n return true;\n }\n\n /**\n * Start TTL cleanup timer.\n */\n private startTTLCleanup(): void {\n const interval = Math.min(this.config.ttlMs, 60000); // At least every minute\n this.ttlTimer = setInterval(() => {\n this.compact();\n }, interval);\n }\n\n /**\n * Dispose resources.\n */\n dispose(): void {\n if (this.ttlTimer) {\n clearInterval(this.ttlTimer);\n this.ttlTimer = undefined;\n }\n this.listeners.clear();\n }\n\n /**\n * Get all current listeners count (for testing).\n */\n getListenerCount(): number {\n return this.listeners.size;\n }\n\n /**\n * Get configuration (for testing).\n */\n getConfig(): EventJournalConfig {\n return { ...this.config };\n }\n}\n","import { z } from 'zod';\n\n// --- Entry Processor Types ---\n\n/**\n * Function executed on the server against a single entry.\n * Receives the current value (or undefined if key doesn't exist).\n * Returns the new value (or undefined to delete the entry).\n */\nexport type EntryProcessorFn<V, R = V> = (\n value: V | undefined,\n key: string,\n args?: unknown,\n) => { value: V | undefined; result?: R };\n\n/**\n * Zod schema for entry processor definition validation.\n */\nexport const EntryProcessorDefSchema = z.object({\n name: z.string().min(1).max(100),\n code: z.string().min(1).max(10000), // Max 10KB code\n args: z.unknown().optional(),\n});\n\n/**\n * Serializable entry processor definition.\n * Code is sent as string and executed in isolated sandbox.\n */\nexport interface EntryProcessorDef<V = unknown, R = V> {\n /** Unique processor name for caching compiled code */\n name: string;\n\n /** JavaScript function body as string */\n code: string;\n\n /** Optional arguments passed to the processor */\n args?: unknown;\n\n /** Type markers (not serialized) */\n __valueType?: V;\n __resultType?: R;\n}\n\n/**\n * Result of entry processor execution.\n */\nexport interface EntryProcessorResult<R = unknown> {\n /** Whether the operation succeeded */\n success: boolean;\n\n /** Custom result returned by processor */\n result?: R;\n\n /** Error message if failed */\n error?: string;\n\n /** New value after processing (for client cache update) */\n newValue?: unknown;\n}\n\n// --- Security: Forbidden Patterns ---\n\n/**\n * Patterns that are denied in processor code for security reasons.\n */\nexport const FORBIDDEN_PATTERNS = [\n /\\beval\\b/,\n /\\bFunction\\b/,\n /\\bprocess\\b/,\n /\\bglobal\\b/,\n /\\brequire\\b/,\n /\\bimport\\b/,\n /\\bfetch\\b/,\n /\\bXMLHttpRequest\\b/,\n /\\bsetTimeout\\b/,\n /\\bsetInterval\\b/,\n /\\bsetImmediate\\b/,\n];\n\n/**\n * Validates processor code against forbidden patterns.\n * Returns true if code is safe, false otherwise.\n */\nexport function validateProcessorCode(code: string): {\n valid: boolean;\n error?: string;\n} {\n for (const pattern of FORBIDDEN_PATTERNS) {\n if (pattern.test(code)) {\n return {\n valid: false,\n error: `Forbidden pattern detected: ${pattern.source}`,\n };\n }\n }\n return { valid: true };\n}\n\n// --- Built-in Processors ---\n\n/**\n * Built-in processors for common operations.\n * These are type-safe and pre-validated.\n */\nexport const BuiltInProcessors = {\n /**\n * Increment numeric value by delta.\n * If value doesn't exist, starts from 0.\n */\n INCREMENT: (delta: number = 1): EntryProcessorDef<number, number> => ({\n name: 'builtin:increment',\n code: `\n const current = value ?? 0;\n const newValue = current + args;\n return { value: newValue, result: newValue };\n `,\n args: delta,\n }),\n\n /**\n * Decrement numeric value by delta.\n * If value doesn't exist, starts from 0.\n */\n DECREMENT: (delta: number = 1): EntryProcessorDef<number, number> => ({\n name: 'builtin:decrement',\n code: `\n const current = value ?? 0;\n const newValue = current - args;\n return { value: newValue, result: newValue };\n `,\n args: delta,\n }),\n\n /**\n * Decrement with floor (won't go below 0).\n * Returns both the new value and whether it was floored.\n */\n DECREMENT_FLOOR: (\n delta: number = 1,\n ): EntryProcessorDef<number, { newValue: number; wasFloored: boolean }> => ({\n name: 'builtin:decrement_floor',\n code: `\n const current = value ?? 0;\n const target = current - args;\n const newValue = Math.max(0, target);\n return {\n value: newValue,\n result: { newValue, wasFloored: target < 0 }\n };\n `,\n args: delta,\n }),\n\n /**\n * Multiply numeric value by factor.\n * If value doesn't exist, starts from 1.\n */\n MULTIPLY: (factor: number): EntryProcessorDef<number, number> => ({\n name: 'builtin:multiply',\n code: `\n const current = value ?? 1;\n const newValue = current * args;\n return { value: newValue, result: newValue };\n `,\n args: factor,\n }),\n\n /**\n * Set value only if key doesn't exist.\n * Returns true if value was set, false if key already existed.\n */\n PUT_IF_ABSENT: <V>(newValue: V): EntryProcessorDef<V, boolean> => ({\n name: 'builtin:put_if_absent',\n code: `\n if (value !== undefined) {\n return { value, result: false };\n }\n return { value: args, result: true };\n `,\n args: newValue,\n }),\n\n /**\n * Replace value only if key exists.\n * Returns the old value if replaced, undefined otherwise.\n */\n REPLACE: <V>(newValue: V): EntryProcessorDef<V, V | undefined> => ({\n name: 'builtin:replace',\n code: `\n if (value === undefined) {\n return { value: undefined, result: undefined };\n }\n return { value: args, result: value };\n `,\n args: newValue,\n }),\n\n /**\n * Replace value only if it matches expected value.\n * Returns true if replaced, false otherwise.\n */\n REPLACE_IF_EQUALS: <V>(\n expectedValue: V,\n newValue: V,\n ): EntryProcessorDef<V, boolean> => ({\n name: 'builtin:replace_if_equals',\n code: `\n if (JSON.stringify(value) === JSON.stringify(args.expected)) {\n return { value: args.newValue, result: true };\n }\n return { value, result: false };\n `,\n args: { expected: expectedValue, newValue },\n }),\n\n /**\n * Delete entry only if value matches.\n * Returns true if deleted, false otherwise.\n */\n DELETE_IF_EQUALS: <V>(expectedValue: V): EntryProcessorDef<V, boolean> => ({\n name: 'builtin:delete_if_equals',\n code: `\n if (JSON.stringify(value) === JSON.stringify(args)) {\n return { value: undefined, result: true };\n }\n return { value, result: false };\n `,\n args: expectedValue,\n }),\n\n /**\n * Append item to array.\n * Creates array if it doesn't exist.\n * Returns new array length.\n */\n ARRAY_PUSH: <T>(item: T): EntryProcessorDef<T[], number> => ({\n name: 'builtin:array_push',\n code: `\n const arr = value ?? [];\n arr.push(args);\n return { value: arr, result: arr.length };\n `,\n args: item,\n }),\n\n /**\n * Remove last item from array.\n * Returns the removed item or undefined.\n */\n ARRAY_POP: <T>(): EntryProcessorDef<T[], T | undefined> => ({\n name: 'builtin:array_pop',\n code: `\n if (!value || value.length === 0) {\n return { value: value ?? [], result: undefined };\n }\n const removed = value.pop();\n return { value, result: removed };\n `,\n }),\n\n /**\n * Remove item from array by value (first occurrence).\n * Returns true if item was found and removed.\n */\n ARRAY_REMOVE: <T>(item: T): EntryProcessorDef<T[], boolean> => ({\n name: 'builtin:array_remove',\n code: `\n if (!value) {\n return { value: [], result: false };\n }\n const idx = value.findIndex(v => JSON.stringify(v) === JSON.stringify(args));\n if (idx === -1) {\n return { value, result: false };\n }\n value.splice(idx, 1);\n return { value, result: true };\n `,\n args: item,\n }),\n\n /**\n * Update nested property using dot notation path.\n * Creates intermediate objects if they don't exist.\n */\n SET_PROPERTY: <V>(\n path: string,\n propValue: unknown,\n ): EntryProcessorDef<V, V> => ({\n name: 'builtin:set_property',\n code: `\n const obj = value ?? {};\n const parts = args.path.split('.');\n let current = obj;\n for (let i = 0; i < parts.length - 1; i++) {\n current[parts[i]] = current[parts[i]] ?? {};\n current = current[parts[i]];\n }\n current[parts[parts.length - 1]] = args.value;\n return { value: obj, result: obj };\n `,\n args: { path, value: propValue },\n }),\n\n /**\n * Delete nested property using dot notation path.\n * Returns the deleted value or undefined.\n */\n DELETE_PROPERTY: <V>(path: string): EntryProcessorDef<V, unknown> => ({\n name: 'builtin:delete_property',\n code: `\n if (!value) {\n return { value, result: undefined };\n }\n const parts = args.split('.');\n let current = value;\n for (let i = 0; i < parts.length - 1; i++) {\n if (!current[parts[i]]) {\n return { value, result: undefined };\n }\n current = current[parts[i]];\n }\n const lastKey = parts[parts.length - 1];\n const deleted = current[lastKey];\n delete current[lastKey];\n return { value, result: deleted };\n `,\n args: path,\n }),\n\n /**\n * Get current value without modifying it.\n * Useful for conditional reads.\n */\n GET: <V>(): EntryProcessorDef<V, V | undefined> => ({\n name: 'builtin:get',\n code: `\n return { value, result: value };\n `,\n }),\n\n /**\n * Conditional update based on version/timestamp.\n * Only updates if current version matches expected.\n * Useful for optimistic locking.\n */\n CONDITIONAL_UPDATE: <V extends { version?: number }>(\n expectedVersion: number,\n newData: Partial<V>,\n ): EntryProcessorDef<V, { updated: boolean; conflict: boolean }> => ({\n name: 'builtin:conditional_update',\n code: `\n if (!value || value.version !== args.expectedVersion) {\n return {\n value,\n result: { updated: false, conflict: true }\n };\n }\n const updated = {\n ...value,\n ...args.newData,\n version: (value.version ?? 0) + 1,\n };\n return {\n value: updated,\n result: { updated: true, conflict: false }\n };\n `,\n args: { expectedVersion, newData },\n }),\n\n /**\n * Merge object properties into existing value.\n * Shallow merge only.\n */\n MERGE: <V extends Record<string, unknown>>(\n properties: Partial<V>,\n ): EntryProcessorDef<V, V> => ({\n name: 'builtin:merge',\n code: `\n const merged = { ...(value ?? {}), ...args };\n return { value: merged, result: merged };\n `,\n args: properties,\n }),\n};\n\n// --- Rate Limiting Configuration ---\n\n/**\n * Rate limiting configuration for processor execution.\n */\nexport interface ProcessorRateLimitConfig {\n /** Max processor executions per second per client */\n maxExecutionsPerSecond: number;\n\n /** Max processor code size in bytes */\n maxCodeSizeBytes: number;\n\n /** Max args size in bytes (JSON stringified) */\n maxArgsSizeBytes: number;\n}\n\n/**\n * Default rate limit configuration.\n */\nexport const DEFAULT_PROCESSOR_RATE_LIMITS: ProcessorRateLimitConfig = {\n maxExecutionsPerSecond: 100,\n maxCodeSizeBytes: 10240, // 10KB\n maxArgsSizeBytes: 1048576, // 1MB\n};\n","import { z } from 'zod';\nimport { Timestamp, HLC } from './HLC';\n\n// --- Merge Context ---\n\n/**\n * Context provided to a conflict resolver during merge operations.\n */\nexport interface MergeContext<V = unknown> {\n /** Map name being modified */\n mapName: string;\n\n /** Entry key being modified */\n key: string;\n\n /** Current server/local value (undefined if key doesn't exist) */\n localValue: V | undefined;\n\n /** Incoming client/remote value */\n remoteValue: V;\n\n /** Local HLC timestamp (undefined if key doesn't exist) */\n localTimestamp?: Timestamp;\n\n /** Remote HLC timestamp */\n remoteTimestamp: Timestamp;\n\n /** Client/node ID that sent the update */\n remoteNodeId: string;\n\n /** Authentication context (optional) */\n auth?: {\n userId?: string;\n roles?: string[];\n metadata?: Record<string, unknown>;\n };\n\n /** Read other entries for cross-key validation */\n readEntry: (key: string) => V | undefined;\n}\n\n// --- Merge Result ---\n\n/**\n * Result of conflict resolution.\n */\nexport type MergeResult<V = unknown> =\n | { action: 'accept'; value: V } // Accept remote value\n | { action: 'reject'; reason: string } // Reject with error\n | { action: 'merge'; value: V } // Custom merged value\n | { action: 'local' }; // Keep local value\n\n// --- Conflict Resolver Function ---\n\n/**\n * Conflict resolver function signature.\n */\nexport type ConflictResolverFn<V = unknown> = (\n context: MergeContext<V>,\n) => MergeResult<V> | Promise<MergeResult<V>>;\n\n// --- Conflict Resolver Definition ---\n\n/**\n * Conflict resolver definition (can be native function or sandboxed code).\n */\nexport interface ConflictResolverDef<V = unknown> {\n /** Unique resolver name */\n name: string;\n\n /** JavaScript function body as string (for sandboxed execution) */\n code?: string;\n\n /** Native function (for trusted server-side resolvers) */\n fn?: ConflictResolverFn<V>;\n\n /** Priority (higher = runs first, default 50) */\n priority?: number;\n\n /** Apply only to specific keys (glob pattern) */\n keyPattern?: string;\n}\n\n// --- Zod Schema for Wire Format ---\n\n/**\n * Zod schema for validating conflict resolver definitions from network.\n */\nexport const ConflictResolverDefSchema = z.object({\n name: z.string().min(1).max(100),\n code: z.string().max(50000).optional(),\n priority: z.number().int().min(0).max(100).default(50),\n keyPattern: z.string().optional(),\n});\n\n// --- Security: Forbidden Patterns ---\n\n/**\n * Patterns that are denied in resolver code for security reasons.\n * Same patterns as EntryProcessor for consistency.\n */\nexport const RESOLVER_FORBIDDEN_PATTERNS = [\n /\\beval\\b/,\n /\\bFunction\\b/,\n /\\bprocess\\b/,\n /\\bglobal\\b/,\n /\\brequire\\b/,\n /\\bimport\\b/,\n /\\bfetch\\b/,\n /\\bXMLHttpRequest\\b/,\n /\\bsetTimeout\\b/,\n /\\bsetInterval\\b/,\n /\\bsetImmediate\\b/,\n];\n\n/**\n * Validates resolver code against forbidden patterns.\n */\nexport function validateResolverCode(code: string): {\n valid: boolean;\n error?: string;\n} {\n for (const pattern of RESOLVER_FORBIDDEN_PATTERNS) {\n if (pattern.test(code)) {\n return {\n valid: false,\n error: `Forbidden pattern detected: ${pattern.source}`,\n };\n }\n }\n return { valid: true };\n}\n\n// --- Rate Limiting Configuration ---\n\n/**\n * Rate limiting configuration for resolver registration.\n */\nexport interface ResolverRateLimitConfig {\n /** Max resolver registrations per client */\n maxResolversPerClient: number;\n\n /** Max resolver code size in bytes */\n maxCodeSizeBytes: number;\n}\n\n/**\n * Default rate limit configuration.\n */\nexport const DEFAULT_RESOLVER_RATE_LIMITS: ResolverRateLimitConfig = {\n maxResolversPerClient: 50,\n maxCodeSizeBytes: 50000, // 50KB\n};\n\n// --- Helper Functions ---\n\n/**\n * Compares two HLC timestamps.\n * Returns negative if a < b, positive if a > b, 0 if equal.\n */\nexport function compareHLCTimestamps(a: Timestamp, b: Timestamp): number {\n return HLC.compare(a, b);\n}\n\n/**\n * Deep merges two objects.\n * Remote values take precedence at each level.\n */\nexport function deepMerge<T extends object>(target: T, source: T): T {\n const result = { ...target };\n\n for (const key of Object.keys(source) as (keyof T)[]) {\n const sourceVal = source[key];\n const targetVal = target[key];\n\n if (\n typeof sourceVal === 'object' &&\n sourceVal !== null &&\n typeof targetVal === 'object' &&\n targetVal !== null &&\n !Array.isArray(sourceVal)\n ) {\n (result as Record<string, unknown>)[key as string] = deepMerge(\n targetVal as object,\n sourceVal as object,\n );\n } else {\n (result as Record<string, unknown>)[key as string] = sourceVal;\n }\n }\n\n return result;\n}\n\n// --- Built-in Resolvers ---\n\n/**\n * Built-in conflict resolvers for common patterns.\n * These are type-safe and pre-validated.\n */\nexport const BuiltInResolvers = {\n /**\n * Standard Last-Write-Wins - accept if remote timestamp is newer.\n */\n LWW: <V>(): ConflictResolverDef<V> => ({\n name: 'builtin:lww',\n fn: (ctx) => {\n if (!ctx.localTimestamp) {\n return { action: 'accept', value: ctx.remoteValue };\n }\n\n const cmp = compareHLCTimestamps(ctx.remoteTimestamp, ctx.localTimestamp);\n if (cmp > 0) {\n return { action: 'accept', value: ctx.remoteValue };\n }\n return { action: 'local' };\n },\n priority: 0, // Lowest priority - fallback\n }),\n\n /**\n * First-Write-Wins - reject if local value exists.\n * Useful for booking systems, unique constraints.\n */\n FIRST_WRITE_WINS: <V>(): ConflictResolverDef<V> => ({\n name: 'builtin:first_write_wins',\n fn: (ctx) => {\n if (ctx.localValue !== undefined) {\n return { action: 'reject', reason: 'Entry already exists' };\n }\n return { action: 'accept', value: ctx.remoteValue };\n },\n priority: 100,\n }),\n\n /**\n * Numeric minimum - keep lowest value.\n * Useful for auction systems (lowest bid wins).\n */\n NUMERIC_MIN: (): ConflictResolverDef<number> => ({\n name: 'builtin:numeric_min',\n fn: (ctx) => {\n const local = ctx.localValue ?? Infinity;\n const remote = ctx.remoteValue;\n return { action: 'merge', value: Math.min(local, remote) };\n },\n priority: 50,\n }),\n\n /**\n * Numeric maximum - keep highest value.\n * Useful for high score tracking.\n */\n NUMERIC_MAX: (): ConflictResolverDef<number> => ({\n name: 'builtin:numeric_max',\n fn: (ctx) => {\n const local = ctx.localValue ?? -Infinity;\n const remote = ctx.remoteValue;\n return { action: 'merge', value: Math.max(local, remote) };\n },\n priority: 50,\n }),\n\n /**\n * Non-negative - reject if value would be negative.\n * Useful for inventory systems.\n */\n NON_NEGATIVE: (): ConflictResolverDef<number> => ({\n name: 'builtin:non_negative',\n fn: (ctx) => {\n if (typeof ctx.remoteValue !== 'number' || ctx.remoteValue < 0) {\n return { action: 'reject', reason: 'Value cannot be negative' };\n }\n return { action: 'accept', value: ctx.remoteValue };\n },\n priority: 90,\n }),\n\n /**\n * Array union - merge arrays by taking union of elements.\n * Useful for tags, categories.\n */\n ARRAY_UNION: <T>(): ConflictResolverDef<T[]> => ({\n name: 'builtin:array_union',\n fn: (ctx) => {\n const local = ctx.localValue ?? [];\n const remote = ctx.remoteValue ?? [];\n const merged = [...new Set([...local, ...remote])];\n return { action: 'merge', value: merged };\n },\n priority: 50,\n }),\n\n /**\n * Deep merge - recursively merge objects.\n * Remote values take precedence at leaf level.\n */\n DEEP_MERGE: <V extends object>(): ConflictResolverDef<V> => ({\n name: 'builtin:deep_merge',\n fn: (ctx) => {\n const local = (ctx.localValue ?? {}) as V;\n const remote = ctx.remoteValue;\n const merged = deepMerge(local, remote);\n return { action: 'merge', value: merged };\n },\n priority: 50,\n }),\n\n /**\n * Server-only - reject all client writes.\n * Useful for server-controlled state.\n */\n SERVER_ONLY: <V>(): ConflictResolverDef<V> => ({\n name: 'builtin:server_only',\n fn: (ctx) => {\n // Server writes have a special node ID or auth role\n if (ctx.auth?.roles?.includes('server') || ctx.remoteNodeId.startsWith('server:')) {\n return { action: 'accept', value: ctx.remoteValue };\n }\n return { action: 'reject', reason: 'Only server can write to this entry' };\n },\n priority: 100,\n }),\n\n /**\n * Owner-only - only the original creator can modify.\n * Requires value to have an `ownerId` property.\n */\n OWNER_ONLY: <V extends { ownerId?: string }>(): ConflictResolverDef<V> => ({\n name: 'builtin:owner_only',\n fn: (ctx) => {\n // If no local value, accept (first write sets owner)\n if (!ctx.localValue) {\n return { action: 'accept', value: ctx.remoteValue };\n }\n\n // Check if remote is from owner\n const ownerId = ctx.localValue.ownerId;\n if (ownerId && ctx.auth?.userId !== ownerId) {\n return { action: 'reject', reason: 'Only owner can modify this entry' };\n }\n\n return { action: 'accept', value: ctx.remoteValue };\n },\n priority: 95,\n }),\n\n /**\n * Immutable - reject any modifications after initial write.\n */\n IMMUTABLE: <V>(): ConflictResolverDef<V> => ({\n name: 'builtin:immutable',\n fn: (ctx) => {\n if (ctx.localValue !== undefined) {\n return { action: 'reject', reason: 'Entry is immutable' };\n }\n return { action: 'accept', value: ctx.remoteValue };\n },\n priority: 100,\n }),\n\n /**\n * Version check - only accept if version increments by 1.\n * Useful for optimistic locking.\n */\n VERSION_INCREMENT: <V extends { version?: number }>(): ConflictResolverDef<V> => ({\n name: 'builtin:version_increment',\n fn: (ctx) => {\n const localVersion = ctx.localValue?.version ?? 0;\n const remoteVersion = ctx.remoteValue?.version ?? 0;\n\n if (remoteVersion !== localVersion + 1) {\n return {\n action: 'reject',\n reason: `Version conflict: expected ${localVersion + 1}, got ${remoteVersion}`,\n };\n }\n return { action: 'accept', value: ctx.remoteValue };\n },\n priority: 90,\n }),\n};\n\n// --- Merge Rejection Event ---\n\n/**\n * Event emitted when a merge is rejected.\n */\nexport interface MergeRejection {\n mapName: string;\n key: string;\n attemptedValue: unknown;\n reason: string;\n timestamp: Timestamp;\n nodeId: string;\n}\n","\nexport type PredicateOp = \n | 'eq' | 'neq' \n | 'gt' | 'gte' \n | 'lt' | 'lte' \n | 'like' | 'regex' \n | 'and' | 'or' | 'not';\n\nexport interface PredicateNode {\n op: PredicateOp;\n attribute?: string;\n value?: any;\n children?: PredicateNode[];\n}\n\nexport class Predicates {\n static equal(attribute: string, value: any): PredicateNode { \n return { op: 'eq', attribute, value }; \n }\n \n static notEqual(attribute: string, value: any): PredicateNode { \n return { op: 'neq', attribute, value }; \n }\n \n static greaterThan(attribute: string, value: any): PredicateNode { \n return { op: 'gt', attribute, value }; \n }\n \n static greaterThanOrEqual(attribute: string, value: any): PredicateNode { \n return { op: 'gte', attribute, value }; \n }\n \n static lessThan(attribute: string, value: any): PredicateNode { \n return { op: 'lt', attribute, value }; \n }\n \n static lessThanOrEqual(attribute: string, value: any): PredicateNode { \n return { op: 'lte', attribute, value }; \n }\n \n static like(attribute: string, pattern: string): PredicateNode { \n return { op: 'like', attribute, value: pattern }; \n }\n \n static regex(attribute: string, pattern: string): PredicateNode { \n return { op: 'regex', attribute, value: pattern }; \n }\n\n static between(attribute: string, from: any, to: any): PredicateNode {\n return {\n op: 'and',\n children: [\n { op: 'gte', attribute, value: from },\n { op: 'lte', attribute, value: to }\n ]\n };\n }\n\n static and(...predicates: PredicateNode[]): PredicateNode { \n return { op: 'and', children: predicates }; \n }\n \n static or(...predicates: PredicateNode[]): PredicateNode { \n return { op: 'or', children: predicates }; \n }\n \n static not(predicate: PredicateNode): PredicateNode { \n return { op: 'not', children: [predicate] }; \n }\n}\n\nexport function evaluatePredicate(predicate: PredicateNode, data: any): boolean {\n if (!data) return false;\n \n switch (predicate.op) {\n case 'and':\n return (predicate.children || []).every(p => evaluatePredicate(p, data));\n case 'or':\n return (predicate.children || []).some(p => evaluatePredicate(p, data));\n case 'not': {\n const child = (predicate.children || [])[0];\n if (!child) return true; // NOT of nothing is true (vacuous)\n return !evaluatePredicate(child, data);\n }\n }\n\n // Leaf nodes require an attribute\n if (!predicate.attribute) return false;\n \n const value = data[predicate.attribute];\n const target = predicate.value;\n\n switch (predicate.op) {\n case 'eq':\n return value === target;\n case 'neq':\n return value !== target;\n case 'gt':\n return value > target;\n case 'gte':\n return value >= target;\n case 'lt':\n return value < target;\n case 'lte':\n return value <= target;\n case 'like':\n if (typeof value !== 'string' || typeof target !== 'string') return false;\n const pattern = target\n .replace(/[.+^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/%/g, '.*')\n .replace(/_/g, '.');\n return new RegExp(`^${pattern}$`, 'i').test(value);\n case 'regex':\n if (typeof value !== 'string' || typeof target !== 'string') return false;\n return new RegExp(target).test(value);\n default:\n return false;\n }\n}\n","import { z } from 'zod';\n\n// --- Write Concern Types ---\n\n/**\n * Write Concern schema - defines when an operation is considered acknowledged.\n */\nexport const WriteConcernSchema = z.enum([\n 'FIRE_AND_FORGET',\n 'MEMORY',\n 'APPLIED',\n 'REPLICATED',\n 'PERSISTED',\n]);\n\nexport type WriteConcernValue = z.infer<typeof WriteConcernSchema>;\n\n// --- Basic Types ---\n\nexport const TimestampSchema = z.object({\n millis: z.union([z.number(), z.bigint()]).transform(Number),\n counter: z.union([z.number(), z.bigint()]).transform(Number),\n nodeId: z.string(),\n});\n\nexport const LWWRecordSchema = z.object({\n value: z.any().nullable(),\n timestamp: TimestampSchema,\n ttlMs: z.number().optional(),\n});\n\nexport const ORMapRecordSchema = z.object({\n value: z.any(),\n timestamp: TimestampSchema,\n tag: z.string(),\n ttlMs: z.number().optional(),\n});\n\n// --- Predicate Types ---\n\nexport const PredicateOpSchema = z.enum([\n 'eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'like', 'regex', 'and', 'or', 'not'\n]);\n\n// Recursive schema for PredicateNode\nexport const PredicateNodeSchema: z.ZodType<any> = z.lazy(() => z.object({\n op: PredicateOpSchema,\n attribute: z.string().optional(),\n value: z.any().optional(),\n children: z.array(PredicateNodeSchema).optional(),\n}));\n\n// --- Query Types ---\n\nexport const QuerySchema = z.object({\n where: z.record(z.string(), z.any()).optional(),\n predicate: PredicateNodeSchema.optional(),\n sort: z.record(z.string(), z.enum(['asc', 'desc'])).optional(),\n limit: z.number().optional(),\n offset: z.number().optional(),\n});\n\n// --- Client Operation Types ---\n\nexport const ClientOpSchema = z.object({\n id: z.string().optional(),\n mapName: z.string(),\n key: z.string(),\n // Permissive opType to match ServerCoordinator behavior logic\n // It can be 'REMOVE', 'OR_ADD', 'OR_REMOVE' or undefined/other (implies PUT/LWW)\n opType: z.string().optional(),\n record: LWWRecordSchema.nullable().optional(),\n orRecord: ORMapRecordSchema.nullable().optional(),\n orTag: z.string().nullable().optional(),\n // Write Concern fields (Phase 5.01)\n writeConcern: WriteConcernSchema.optional(),\n timeout: z.number().optional(),\n});\n\n// --- Message Schemas ---\n\nexport const AuthMessageSchema = z.object({\n type: z.literal('AUTH'),\n token: z.string(),\n});\n\nexport const QuerySubMessageSchema = z.object({\n type: z.literal('QUERY_SUB'),\n payload: z.object({\n queryId: z.string(),\n mapName: z.string(),\n query: QuerySchema,\n }),\n});\n\nexport const QueryUnsubMessageSchema = z.object({\n type: z.literal('QUERY_UNSUB'),\n payload: z.object({\n queryId: z.string(),\n }),\n});\n\nexport const ClientOpMessageSchema = z.object({\n type: z.literal('CLIENT_OP'),\n payload: ClientOpSchema,\n});\n\nexport const OpBatchMessageSchema = z.object({\n type: z.literal('OP_BATCH'),\n payload: z.object({\n ops: z.array(ClientOpSchema),\n // Batch-level Write Concern (can be overridden per-op)\n writeConcern: WriteConcernSchema.optional(),\n timeout: z.number().optional(),\n }),\n});\n\nexport const SyncInitMessageSchema = z.object({\n type: z.literal('SYNC_INIT'),\n mapName: z.string(),\n lastSyncTimestamp: z.number().optional(),\n});\n\nexport const SyncRespRootMessageSchema = z.object({\n type: z.literal('SYNC_RESP_ROOT'),\n payload: z.object({\n mapName: z.string(),\n rootHash: z.number(),\n timestamp: TimestampSchema,\n }),\n});\n\nexport const SyncRespBucketsMessageSchema = z.object({\n type: z.literal('SYNC_RESP_BUCKETS'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n buckets: z.record(z.string(), z.number()),\n }),\n});\n\nexport const SyncRespLeafMessageSchema = z.object({\n type: z.literal('SYNC_RESP_LEAF'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n records: z.array(z.object({\n key: z.string(),\n record: LWWRecordSchema,\n })),\n }),\n});\n\nexport const MerkleReqBucketMessageSchema = z.object({\n type: z.literal('MERKLE_REQ_BUCKET'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n }),\n});\n\nexport const LockRequestSchema = z.object({\n type: z.literal('LOCK_REQUEST'),\n payload: z.object({\n requestId: z.string(),\n name: z.string(),\n ttl: z.number().optional(),\n }),\n});\n\nexport const LockReleaseSchema = z.object({\n type: z.literal('LOCK_RELEASE'),\n payload: z.object({\n requestId: z.string().optional(),\n name: z.string(),\n fencingToken: z.number(),\n }),\n});\n\n// --- Topic Messages ---\n\nexport const TopicSubSchema = z.object({\n type: z.literal('TOPIC_SUB'),\n payload: z.object({\n topic: z.string(),\n }),\n});\n\nexport const TopicUnsubSchema = z.object({\n type: z.literal('TOPIC_UNSUB'),\n payload: z.object({\n topic: z.string(),\n }),\n});\n\nexport const TopicPubSchema = z.object({\n type: z.literal('TOPIC_PUB'),\n payload: z.object({\n topic: z.string(),\n data: z.any(),\n }),\n});\n\nexport const TopicMessageEventSchema = z.object({\n type: z.literal('TOPIC_MESSAGE'),\n payload: z.object({\n topic: z.string(),\n data: z.any(),\n publisherId: z.string().optional(),\n timestamp: z.number(),\n }),\n});\n\n// --- PN Counter Messages (Phase 5.2) ---\n\nexport const PNCounterStateObjectSchema = z.object({\n p: z.record(z.string(), z.number()), // positive counts per node\n n: z.record(z.string(), z.number()), // negative counts per node\n});\n\nexport const CounterRequestSchema = z.object({\n type: z.literal('COUNTER_REQUEST'),\n payload: z.object({\n name: z.string(),\n }),\n});\n\nexport const CounterSyncSchema = z.object({\n type: z.literal('COUNTER_SYNC'),\n payload: z.object({\n name: z.string(),\n state: PNCounterStateObjectSchema,\n }),\n});\n\nexport const CounterResponseSchema = z.object({\n type: z.literal('COUNTER_RESPONSE'),\n payload: z.object({\n name: z.string(),\n state: PNCounterStateObjectSchema,\n }),\n});\n\nexport const CounterUpdateSchema = z.object({\n type: z.literal('COUNTER_UPDATE'),\n payload: z.object({\n name: z.string(),\n state: PNCounterStateObjectSchema,\n }),\n});\n\n// --- Heartbeat Messages ---\n\nexport const PingMessageSchema = z.object({\n type: z.literal('PING'),\n timestamp: z.number(), // Client's Date.now()\n});\n\nexport const PongMessageSchema = z.object({\n type: z.literal('PONG'),\n timestamp: z.number(), // Echo back client's timestamp\n serverTime: z.number(), // Server's Date.now() (for clock skew detection)\n});\n\n// --- Batched Messages ---\n\n/**\n * BATCH: Server sends multiple messages batched together.\n * Uses length-prefixed binary format for efficiency.\n * Format: [4 bytes: count][4 bytes: len1][msg1][4 bytes: len2][msg2]...\n */\nexport const BatchMessageSchema = z.object({\n type: z.literal('BATCH'),\n count: z.number(),\n data: z.instanceof(Uint8Array),\n});\n\n// --- ORMap Sync Messages ---\n\n/**\n * ORMAP_SYNC_INIT: Client initiates ORMap sync\n * Sends root hash and bucket hashes to server\n */\nexport const ORMapSyncInitSchema = z.object({\n type: z.literal('ORMAP_SYNC_INIT'),\n mapName: z.string(),\n rootHash: z.number(),\n bucketHashes: z.record(z.string(), z.number()), // path -> hash\n lastSyncTimestamp: z.number().optional(),\n});\n\n/**\n * ORMAP_SYNC_RESP_ROOT: Server responds with its root hash\n */\nexport const ORMapSyncRespRootSchema = z.object({\n type: z.literal('ORMAP_SYNC_RESP_ROOT'),\n payload: z.object({\n mapName: z.string(),\n rootHash: z.number(),\n timestamp: TimestampSchema,\n }),\n});\n\n/**\n * ORMAP_SYNC_RESP_BUCKETS: Server sends bucket hashes for comparison\n */\nexport const ORMapSyncRespBucketsSchema = z.object({\n type: z.literal('ORMAP_SYNC_RESP_BUCKETS'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n buckets: z.record(z.string(), z.number()),\n }),\n});\n\n/**\n * ORMAP_MERKLE_REQ_BUCKET: Client requests bucket details\n */\nexport const ORMapMerkleReqBucketSchema = z.object({\n type: z.literal('ORMAP_MERKLE_REQ_BUCKET'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n }),\n});\n\n/**\n * ORMAP_SYNC_RESP_LEAF: Server sends actual records for differing keys\n */\nexport const ORMapSyncRespLeafSchema = z.object({\n type: z.literal('ORMAP_SYNC_RESP_LEAF'),\n payload: z.object({\n mapName: z.string(),\n path: z.string(),\n entries: z.array(z.object({\n key: z.string(),\n records: z.array(ORMapRecordSchema),\n tombstones: z.array(z.string()), // Tombstone tags for this key's records\n })),\n }),\n});\n\n/**\n * ORMAP_DIFF_REQUEST: Client requests data for specific keys\n */\nexport const ORMapDiffRequestSchema = z.object({\n type: z.literal('ORMAP_DIFF_REQUEST'),\n payload: z.object({\n mapName: z.string(),\n keys: z.array(z.string()),\n }),\n});\n\n/**\n * ORMAP_DIFF_RESPONSE: Server responds with data for requested keys\n */\nexport const ORMapDiffResponseSchema = z.object({\n type: z.literal('ORMAP_DIFF_RESPONSE'),\n payload: z.object({\n mapName: z.string(),\n entries: z.array(z.object({\n key: z.string(),\n records: z.array(ORMapRecordSchema),\n tombstones: z.array(z.string()),\n })),\n }),\n});\n\n/**\n * ORMAP_PUSH_DIFF: Client pushes local diffs to server\n */\nexport const ORMapPushDiffSchema = z.object({\n type: z.literal('ORMAP_PUSH_DIFF'),\n payload: z.object({\n mapName: z.string(),\n entries: z.array(z.object({\n key: z.string(),\n records: z.array(ORMapRecordSchema),\n tombstones: z.array(z.string()),\n })),\n }),\n});\n\n// --- Phase 4: Partition Map Schemas ---\n\n/**\n * PARTITION_MAP_REQUEST: Client requests current partition map\n */\nexport const PartitionMapRequestSchema = z.object({\n type: z.literal('PARTITION_MAP_REQUEST'),\n payload: z.object({\n currentVersion: z.number().optional(),\n }).optional(),\n});\n\n// --- Entry Processor Messages (Phase 5.03) ---\n\n/**\n * Entry processor definition schema.\n */\nexport const EntryProcessorSchema = z.object({\n name: z.string().min(1).max(100),\n code: z.string().min(1).max(10000),\n args: z.unknown().optional(),\n});\n\n/**\n * ENTRY_PROCESS: Client requests atomic operation on single key.\n */\nexport const EntryProcessRequestSchema = z.object({\n type: z.literal('ENTRY_PROCESS'),\n requestId: z.string(),\n mapName: z.string(),\n key: z.string(),\n processor: EntryProcessorSchema,\n});\n\n/**\n * ENTRY_PROCESS_BATCH: Client requests atomic operation on multiple keys.\n */\nexport const EntryProcessBatchRequestSchema = z.object({\n type: z.literal('ENTRY_PROCESS_BATCH'),\n requestId: z.string(),\n mapName: z.string(),\n keys: z.array(z.string()),\n processor: EntryProcessorSchema,\n});\n\n/**\n * ENTRY_PROCESS_RESPONSE: Server responds to single-key processor request.\n */\nexport const EntryProcessResponseSchema = z.object({\n type: z.literal('ENTRY_PROCESS_RESPONSE'),\n requestId: z.string(),\n success: z.boolean(),\n result: z.unknown().optional(),\n newValue: z.unknown().optional(),\n error: z.string().optional(),\n});\n\n/**\n * Individual key result in batch response.\n */\nexport const EntryProcessKeyResultSchema = z.object({\n success: z.boolean(),\n result: z.unknown().optional(),\n newValue: z.unknown().optional(),\n error: z.string().optional(),\n});\n\n/**\n * ENTRY_PROCESS_BATCH_RESPONSE: Server responds to multi-key processor request.\n */\nexport const EntryProcessBatchResponseSchema = z.object({\n type: z.literal('ENTRY_PROCESS_BATCH_RESPONSE'),\n requestId: z.string(),\n results: z.record(z.string(), EntryProcessKeyResultSchema),\n});\n\n// --- Event Journal Messages (Phase 5.04) ---\n\n/**\n * Journal event type schema.\n */\nexport const JournalEventTypeSchema = z.enum(['PUT', 'UPDATE', 'DELETE']);\n\n/**\n * Journal event data (serialized for network).\n */\nexport const JournalEventDataSchema = z.object({\n sequence: z.string(), // bigint as string\n type: JournalEventTypeSchema,\n mapName: z.string(),\n key: z.string(),\n value: z.unknown().optional(),\n previousValue: z.unknown().optional(),\n timestamp: TimestampSchema,\n nodeId: z.string(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n});\n\n/**\n * JOURNAL_SUBSCRIBE: Client subscribes to journal events.\n */\nexport const JournalSubscribeRequestSchema = z.object({\n type: z.literal('JOURNAL_SUBSCRIBE'),\n requestId: z.string(),\n fromSequence: z.string().optional(), // bigint as string\n mapName: z.string().optional(),\n types: z.array(JournalEventTypeSchema).optional(),\n});\n\n/**\n * JOURNAL_UNSUBSCRIBE: Client unsubscribes from journal events.\n */\nexport const JournalUnsubscribeRequestSchema = z.object({\n type: z.literal('JOURNAL_UNSUBSCRIBE'),\n subscriptionId: z.string(),\n});\n\n/**\n * JOURNAL_EVENT: Server sends journal event to client.\n */\nexport const JournalEventMessageSchema = z.object({\n type: z.literal('JOURNAL_EVENT'),\n event: JournalEventDataSchema,\n});\n\n/**\n * JOURNAL_READ: Client requests events from journal.\n */\nexport const JournalReadRequestSchema = z.object({\n type: z.literal('JOURNAL_READ'),\n requestId: z.string(),\n fromSequence: z.string(),\n limit: z.number().optional(),\n mapName: z.string().optional(),\n});\n\n/**\n * JOURNAL_READ_RESPONSE: Server responds with journal events.\n */\nexport const JournalReadResponseSchema = z.object({\n type: z.literal('JOURNAL_READ_RESPONSE'),\n requestId: z.string(),\n events: z.array(JournalEventDataSchema),\n hasMore: z.boolean(),\n});\n\n// --- Conflict Resolver Messages (Phase 5.05) ---\n\n/**\n * Conflict resolver definition schema (wire format).\n */\nexport const ConflictResolverSchema = z.object({\n name: z.string().min(1).max(100),\n code: z.string().max(50000),\n priority: z.number().int().min(0).max(100).optional(),\n keyPattern: z.string().optional(),\n});\n\n/**\n * REGISTER_RESOLVER: Client registers a conflict resolver on server.\n */\nexport const RegisterResolverRequestSchema = z.object({\n type: z.literal('REGISTER_RESOLVER'),\n requestId: z.string(),\n mapName: z.string(),\n resolver: ConflictResolverSchema,\n});\n\n/**\n * REGISTER_RESOLVER_RESPONSE: Server acknowledges resolver registration.\n */\nexport const RegisterResolverResponseSchema = z.object({\n type: z.literal('REGISTER_RESOLVER_RESPONSE'),\n requestId: z.string(),\n success: z.boolean(),\n error: z.string().optional(),\n});\n\n/**\n * UNREGISTER_RESOLVER: Client unregisters a conflict resolver.\n */\nexport const UnregisterResolverRequestSchema = z.object({\n type: z.literal('UNREGISTER_RESOLVER'),\n requestId: z.string(),\n mapName: z.string(),\n resolverName: z.string(),\n});\n\n/**\n * UNREGISTER_RESOLVER_RESPONSE: Server acknowledges resolver unregistration.\n */\nexport const UnregisterResolverResponseSchema = z.object({\n type: z.literal('UNREGISTER_RESOLVER_RESPONSE'),\n requestId: z.string(),\n success: z.boolean(),\n error: z.string().optional(),\n});\n\n/**\n * MERGE_REJECTED: Server notifies client that a merge was rejected.\n */\nexport const MergeRejectedMessageSchema = z.object({\n type: z.literal('MERGE_REJECTED'),\n mapName: z.string(),\n key: z.string(),\n attemptedValue: z.unknown(),\n reason: z.string(),\n timestamp: TimestampSchema,\n});\n\n/**\n * LIST_RESOLVERS: Client requests list of registered resolvers.\n */\nexport const ListResolversRequestSchema = z.object({\n type: z.literal('LIST_RESOLVERS'),\n requestId: z.string(),\n mapName: z.string().optional(),\n});\n\n/**\n * LIST_RESOLVERS_RESPONSE: Server responds with registered resolvers.\n */\nexport const ListResolversResponseSchema = z.object({\n type: z.literal('LIST_RESOLVERS_RESPONSE'),\n requestId: z.string(),\n resolvers: z.array(z.object({\n mapName: z.string(),\n name: z.string(),\n priority: z.number().optional(),\n keyPattern: z.string().optional(),\n })),\n});\n\n// --- Write Concern Response Schemas (Phase 5.01) ---\n\n/**\n * Individual operation result within a batch ACK\n */\nexport const OpResultSchema = z.object({\n opId: z.string(),\n success: z.boolean(),\n achievedLevel: WriteConcernSchema,\n error: z.string().optional(),\n});\n\n/**\n * OP_ACK: Server acknowledges write operations\n * Extended to support Write Concern levels\n */\nexport const OpAckMessageSchema = z.object({\n type: z.literal('OP_ACK'),\n payload: z.object({\n /** ID of the last operation in the batch (for backwards compatibility) */\n lastId: z.string(),\n /** Write Concern level achieved (for simple ACKs) */\n achievedLevel: WriteConcernSchema.optional(),\n /** Per-operation results (for batch operations with mixed Write Concern) */\n results: z.array(OpResultSchema).optional(),\n }),\n});\n\n/**\n * OP_REJECTED: Server rejects a write operation\n */\nexport const OpRejectedMessageSchema = z.object({\n type: z.literal('OP_REJECTED'),\n payload: z.object({\n /** Operation ID that was rejected */\n opId: z.string(),\n /** Reason for rejection */\n reason: z.string(),\n /** Error code */\n code: z.number().optional(),\n }),\n});\n\n// --- Union Schema ---\n\nexport const MessageSchema = z.discriminatedUnion('type', [\n AuthMessageSchema,\n QuerySubMessageSchema,\n QueryUnsubMessageSchema,\n ClientOpMessageSchema,\n OpBatchMessageSchema,\n SyncInitMessageSchema,\n SyncRespRootMessageSchema,\n SyncRespBucketsMessageSchema,\n SyncRespLeafMessageSchema,\n MerkleReqBucketMessageSchema,\n LockRequestSchema,\n LockReleaseSchema,\n TopicSubSchema,\n TopicUnsubSchema,\n TopicPubSchema,\n PingMessageSchema,\n PongMessageSchema,\n // ORMap Sync Messages\n ORMapSyncInitSchema,\n ORMapSyncRespRootSchema,\n ORMapSyncRespBucketsSchema,\n ORMapMerkleReqBucketSchema,\n ORMapSyncRespLeafSchema,\n ORMapDiffRequestSchema,\n ORMapDiffResponseSchema,\n ORMapPushDiffSchema,\n // Phase 4: Partition Map\n PartitionMapRequestSchema,\n // Phase 5.2: PN Counter\n CounterRequestSchema,\n CounterSyncSchema,\n // Phase 5.03: Entry Processor\n EntryProcessRequestSchema,\n EntryProcessBatchRequestSchema,\n EntryProcessResponseSchema,\n EntryProcessBatchResponseSchema,\n // Phase 5.04: Event Journal\n JournalSubscribeRequestSchema,\n JournalUnsubscribeRequestSchema,\n JournalEventMessageSchema,\n JournalReadRequestSchema,\n JournalReadResponseSchema,\n // Phase 5.05: Conflict Resolver\n RegisterResolverRequestSchema,\n RegisterResolverResponseSchema,\n UnregisterResolverRequestSchema,\n UnregisterResolverResponseSchema,\n MergeRejectedMessageSchema,\n ListResolversRequestSchema,\n ListResolversResponseSchema,\n]);\n\n// --- Type Inference ---\n\nexport type Timestamp = z.infer<typeof TimestampSchema>;\nexport type LWWRecord<V = any> = z.infer<typeof LWWRecordSchema>; // Generic placeholder\nexport type ORMapRecord<V = any> = z.infer<typeof ORMapRecordSchema>; // Generic placeholder\n// export type PredicateNode = z.infer<typeof PredicateNodeSchema>; // Conflict with predicate.ts\nexport type Query = z.infer<typeof QuerySchema>;\nexport type ClientOp = z.infer<typeof ClientOpSchema>;\nexport type Message = z.infer<typeof MessageSchema>;\nexport type PingMessage = z.infer<typeof PingMessageSchema>;\nexport type PongMessage = z.infer<typeof PongMessageSchema>;\nexport type BatchMessage = z.infer<typeof BatchMessageSchema>;\n\n// Write Concern types (Phase 5.01)\nexport type OpAckMessage = z.infer<typeof OpAckMessageSchema>;\nexport type OpRejectedMessage = z.infer<typeof OpRejectedMessageSchema>;\nexport type OpResult = z.infer<typeof OpResultSchema>;\n\n// Entry Processor types (Phase 5.03)\nexport type EntryProcessRequest = z.infer<typeof EntryProcessRequestSchema>;\nexport type EntryProcessBatchRequest = z.infer<typeof EntryProcessBatchRequestSchema>;\nexport type EntryProcessResponse = z.infer<typeof EntryProcessResponseSchema>;\nexport type EntryProcessBatchResponse = z.infer<typeof EntryProcessBatchResponseSchema>;\nexport type EntryProcessKeyResult = z.infer<typeof EntryProcessKeyResultSchema>;\n\n// Event Journal types (Phase 5.04)\nexport type JournalEventType = z.infer<typeof JournalEventTypeSchema>;\nexport type JournalEventData = z.infer<typeof JournalEventDataSchema>;\nexport type JournalSubscribeRequest = z.infer<typeof JournalSubscribeRequestSchema>;\nexport type JournalUnsubscribeRequest = z.infer<typeof JournalUnsubscribeRequestSchema>;\nexport type JournalEventMessage = z.infer<typeof JournalEventMessageSchema>;\nexport type JournalReadRequest = z.infer<typeof JournalReadRequestSchema>;\nexport type JournalReadResponse = z.infer<typeof JournalReadResponseSchema>;\n\n// Conflict Resolver types (Phase 5.05)\nexport type ConflictResolver = z.infer<typeof ConflictResolverSchema>;\nexport type RegisterResolverRequest = z.infer<typeof RegisterResolverRequestSchema>;\nexport type RegisterResolverResponse = z.infer<typeof RegisterResolverResponseSchema>;\nexport type UnregisterResolverRequest = z.infer<typeof UnregisterResolverRequestSchema>;\nexport type UnregisterResolverResponse = z.infer<typeof UnregisterResolverResponseSchema>;\nexport type MergeRejectedMessage = z.infer<typeof MergeRejectedMessageSchema>;\nexport type ListResolversRequest = z.infer<typeof ListResolversRequestSchema>;\nexport type ListResolversResponse = z.infer<typeof ListResolversResponseSchema>;\n","/**\n * Write Concern - Configurable Acknowledgment Levels\n *\n * Write Concern defines when a write operation is considered successful.\n * Similar to MongoDB's writeConcern, Kafka's acks, and Cassandra's consistency levels.\n */\n\n/**\n * Write Concern levels - determines when an operation is acknowledged.\n *\n * Levels are ordered by durability guarantee (lowest to highest):\n * FIRE_AND_FORGET < MEMORY < APPLIED < REPLICATED < PERSISTED\n */\nexport enum WriteConcern {\n /**\n * FIRE_AND_FORGET (acks=0)\n * - ACK sent immediately after server receives the message\n * - Operation may be lost if server crashes before processing\n * - Maximum throughput, minimum latency\n * - Use case: metrics, logs, non-critical data\n */\n FIRE_AND_FORGET = 'FIRE_AND_FORGET',\n\n /**\n * MEMORY (acks=1, default) - current Early ACK behavior\n * - ACK sent after validation and queuing for processing\n * - Operation is in memory but not yet applied to CRDT\n * - Use case: most operations, real-time updates\n */\n MEMORY = 'MEMORY',\n\n /**\n * APPLIED\n * - ACK sent after operation is applied to CRDT in memory\n * - Data is readable on this node immediately after ACK\n * - Use case: operations requiring immediate consistency on the node\n */\n APPLIED = 'APPLIED',\n\n /**\n * REPLICATED\n * - ACK sent after operation is broadcast to cluster (CLUSTER_EVENT sent)\n * - Data survives primary node failure\n * - Use case: important data requiring cluster durability\n */\n REPLICATED = 'REPLICATED',\n\n /**\n * PERSISTED\n * - ACK sent after operation is written to storage on primary node\n * - Data survives node restart\n * - Use case: critical data (financial transactions, audit logs)\n */\n PERSISTED = 'PERSISTED',\n}\n\n/**\n * Default timeout for Write Concern acknowledgments (ms)\n */\nexport const DEFAULT_WRITE_CONCERN_TIMEOUT = 5000;\n\n/**\n * Write options for PUT/REMOVE operations\n */\nexport interface WriteOptions {\n /**\n * Write acknowledgment level.\n * @default WriteConcern.MEMORY\n */\n writeConcern?: WriteConcern;\n\n /**\n * Timeout for waiting for acknowledgment (ms).\n * Applies to APPLIED, REPLICATED, PERSISTED levels.\n * @default 5000\n */\n timeout?: number;\n}\n\n/**\n * Result of a write operation\n */\nexport interface WriteResult {\n /** Whether the operation achieved the requested Write Concern level */\n success: boolean;\n\n /** Operation ID */\n opId: string;\n\n /** The Write Concern level actually achieved */\n achievedLevel: WriteConcern;\n\n /** Time taken to achieve the level (ms) */\n latencyMs: number;\n\n /** Error message if success=false */\n error?: string;\n}\n\n/**\n * Internal structure for tracking pending write acknowledgments\n */\nexport interface PendingWrite {\n /** Operation ID */\n opId: string;\n\n /** Target Write Concern level */\n writeConcern: WriteConcern;\n\n /** Timestamp when operation was registered */\n timestamp: number;\n\n /** Timeout duration (ms) */\n timeout: number;\n\n /** Promise resolve callback */\n resolve: (result: WriteResult) => void;\n\n /** Promise reject callback */\n reject: (error: Error) => void;\n\n /** Timeout handle for cleanup */\n timeoutHandle?: ReturnType<typeof setTimeout>;\n\n /** Set of levels that have been achieved */\n achievedLevels: Set<WriteConcern>;\n}\n\n/**\n * Ordered list of Write Concern levels (lowest to highest)\n */\nexport const WRITE_CONCERN_ORDER: readonly WriteConcern[] = [\n WriteConcern.FIRE_AND_FORGET,\n WriteConcern.MEMORY,\n WriteConcern.APPLIED,\n WriteConcern.REPLICATED,\n WriteConcern.PERSISTED,\n] as const;\n\n/**\n * Check if a target Write Concern level is achieved based on achieved levels.\n *\n * @param achieved - Set of achieved Write Concern levels\n * @param target - Target Write Concern level to check\n * @returns true if target level (or higher) is achieved\n */\nexport function isWriteConcernAchieved(\n achieved: Set<WriteConcern>,\n target: WriteConcern\n): boolean {\n const targetIndex = WRITE_CONCERN_ORDER.indexOf(target);\n const achievedIndex = Math.max(\n ...Array.from(achieved).map((l) => WRITE_CONCERN_ORDER.indexOf(l))\n );\n return achievedIndex >= targetIndex;\n}\n\n/**\n * Get the highest achieved Write Concern level from a set of achieved levels.\n *\n * @param achieved - Set of achieved Write Concern levels\n * @returns The highest achieved level\n */\nexport function getHighestWriteConcernLevel(\n achieved: Set<WriteConcern>\n): WriteConcern {\n for (let i = WRITE_CONCERN_ORDER.length - 1; i >= 0; i--) {\n if (achieved.has(WRITE_CONCERN_ORDER[i])) {\n return WRITE_CONCERN_ORDER[i];\n }\n }\n return WriteConcern.FIRE_AND_FORGET;\n}\n","/**\n * Cluster types for Phase 4: Clustering Improvements\n *\n * These types are shared between client and server packages\n * for partition-aware routing and cluster communication.\n */\n\n// ============================================\n// Node and Cluster Status\n// ============================================\n\nexport type NodeStatus = 'ACTIVE' | 'JOINING' | 'LEAVING' | 'SUSPECTED' | 'FAILED';\n\nexport interface NodeInfo {\n nodeId: string;\n endpoints: {\n websocket: string; // ws://host:port or wss://host:port\n http?: string; // Optional REST endpoint\n };\n status: NodeStatus;\n}\n\n// ============================================\n// Partition Map\n// ============================================\n\nexport interface PartitionInfo {\n partitionId: number;\n ownerNodeId: string;\n backupNodeIds: string[];\n}\n\nexport interface PartitionMap {\n version: number; // Incremented on topology change\n partitionCount: number; // 271 by default\n nodes: NodeInfo[];\n partitions: PartitionInfo[];\n generatedAt: number; // Timestamp when map was generated\n}\n\n// ============================================\n// Partition Map Protocol Messages\n// ============================================\n\nexport interface PartitionMapMessage {\n type: 'PARTITION_MAP';\n payload: PartitionMap;\n}\n\nexport interface PartitionMapRequestMessage {\n type: 'PARTITION_MAP_REQUEST';\n payload?: {\n currentVersion?: number;\n };\n}\n\nexport interface PartitionChange {\n partitionId: number;\n previousOwner: string;\n newOwner: string;\n reason: 'REBALANCE' | 'FAILOVER' | 'JOIN' | 'LEAVE';\n}\n\nexport interface PartitionMapDeltaMessage {\n type: 'PARTITION_MAP_DELTA';\n payload: {\n version: number;\n previousVersion: number;\n changes: PartitionChange[];\n timestamp: number;\n };\n}\n\n// ============================================\n// Routing Errors\n// ============================================\n\nexport interface NotOwnerError {\n code: 'NOT_OWNER';\n message: string;\n hint: {\n partitionId: number;\n currentOwner: string;\n mapVersion: number;\n };\n}\n\nexport interface StaleMapError {\n code: 'STALE_MAP';\n message: string;\n hint: {\n clientVersion: number;\n serverVersion: number;\n };\n}\n\nexport type RoutingError = NotOwnerError | StaleMapError;\n\n// ============================================\n// Connection Pool Configuration\n// ============================================\n\nexport interface ConnectionPoolConfig {\n /** Maximum connections per node (default: 1) */\n maxConnectionsPerNode: number;\n /** Connection timeout in ms (default: 5000) */\n connectionTimeoutMs: number;\n /** Health check interval in ms (default: 10000) */\n healthCheckIntervalMs: number;\n /** Reconnect delay base in ms (default: 1000) */\n reconnectDelayMs: number;\n /** Maximum reconnect delay in ms (default: 30000) */\n maxReconnectDelayMs: number;\n /** Maximum reconnect attempts before marking unhealthy (default: 5) */\n maxReconnectAttempts: number;\n}\n\nexport const DEFAULT_CONNECTION_POOL_CONFIG: ConnectionPoolConfig = {\n maxConnectionsPerNode: 1,\n connectionTimeoutMs: 5000,\n healthCheckIntervalMs: 10000,\n reconnectDelayMs: 1000,\n maxReconnectDelayMs: 30000,\n maxReconnectAttempts: 5,\n};\n\n// ============================================\n// Partition Router Configuration\n// ============================================\n\nexport interface PartitionRouterConfig {\n /** Fallback mode when routing fails: 'forward' uses primary, 'error' throws */\n fallbackMode: 'forward' | 'error';\n /** How often to refresh stale partition map in ms (default: 30000) */\n mapRefreshIntervalMs: number;\n /** Max staleness before forcing refresh in ms (default: 60000) */\n maxMapStalenessMs: number;\n}\n\nexport const DEFAULT_PARTITION_ROUTER_CONFIG: PartitionRouterConfig = {\n fallbackMode: 'forward',\n mapRefreshIntervalMs: 30000,\n maxMapStalenessMs: 60000,\n};\n\n// ============================================\n// Cluster Client Configuration\n// ============================================\n\n/**\n * Circuit breaker configuration.\n */\nexport interface CircuitBreakerConfig {\n /** Number of failures before opening circuit (default: 5) */\n failureThreshold: number;\n /** Time in ms before attempting to close circuit (default: 30000) */\n resetTimeoutMs: number;\n}\n\nexport const DEFAULT_CIRCUIT_BREAKER_CONFIG: CircuitBreakerConfig = {\n failureThreshold: 5,\n resetTimeoutMs: 30000,\n};\n\nexport interface ClusterClientConfig {\n /** Enable cluster mode */\n enabled: boolean;\n /** Initial seed nodes to connect to */\n seedNodes: string[];\n /** Routing mode: 'direct' routes to owner, 'forward' uses server forwarding */\n routingMode: 'direct' | 'forward';\n /** Connection pool configuration */\n connectionPool?: Partial<ConnectionPoolConfig>;\n /** Partition router configuration */\n routing?: Partial<PartitionRouterConfig>;\n /** Circuit breaker configuration */\n circuitBreaker?: Partial<CircuitBreakerConfig>;\n}\n\n// ============================================\n// Node Health\n// ============================================\n\nexport type ConnectionState =\n | 'DISCONNECTED'\n | 'CONNECTING'\n | 'CONNECTED'\n | 'AUTHENTICATED'\n | 'RECONNECTING'\n | 'FAILED';\n\nexport interface NodeHealth {\n nodeId: string;\n state: ConnectionState;\n lastSeen: number;\n latencyMs: number;\n reconnectAttempts: number;\n}\n\n// ============================================\n// Cluster Events (for EventEmitter)\n// ============================================\n\nexport interface ClusterEvents {\n 'node:connected': { nodeId: string };\n 'node:disconnected': { nodeId: string; reason: string };\n 'node:healthy': { nodeId: string };\n 'node:unhealthy': { nodeId: string; reason: string };\n 'partitionMap:updated': { version: number; changesCount: number };\n 'partitionMap:stale': { currentVersion: number; lastRefresh: number };\n 'routing:miss': { key: string; expectedOwner: string; actualOwner: string };\n}\n\n// ============================================\n// Migration State Machine (Task 03)\n// ============================================\n\nexport enum PartitionState {\n STABLE = 'STABLE', // Normal operation\n MIGRATING = 'MIGRATING', // Data being transferred\n SYNC = 'SYNC', // Verifying consistency\n FAILED = 'FAILED', // Migration failed, needs retry\n}\n\nexport interface PartitionMigration {\n partitionId: number;\n state: PartitionState;\n sourceNode: string;\n targetNode: string;\n startTime: number;\n bytesTransferred: number;\n totalBytes: number;\n retryCount: number;\n}\n\nexport interface MigrationConfig {\n /** Partitions per batch (default: 10) */\n batchSize: number;\n /** Delay between batches in ms (default: 5000) */\n batchIntervalMs: number;\n /** Bytes per chunk (default: 64KB) */\n transferChunkSize: number;\n /** Retries per partition (default: 3) */\n maxRetries: number;\n /** Sync phase timeout in ms (default: 30000) */\n syncTimeoutMs: number;\n /** Concurrent transfers (default: 4) */\n parallelTransfers: number;\n}\n\nexport const DEFAULT_MIGRATION_CONFIG: MigrationConfig = {\n batchSize: 10,\n batchIntervalMs: 5000,\n transferChunkSize: 65536, // 64KB\n maxRetries: 3,\n syncTimeoutMs: 30000,\n parallelTransfers: 4,\n};\n\nexport interface MigrationStatus {\n inProgress: boolean;\n active: PartitionMigration[];\n queued: number;\n completed: number;\n failed: number;\n estimatedTimeRemainingMs: number;\n}\n\nexport interface MigrationMetrics {\n migrationsStarted: number;\n migrationsCompleted: number;\n migrationsFailed: number;\n chunksTransferred: number;\n bytesTransferred: number;\n activeMigrations: number;\n queuedMigrations: number;\n}\n\n// ============================================\n// Migration Protocol Messages (Task 03)\n// ============================================\n\nexport interface MigrationStartMessage {\n type: 'MIGRATION_START';\n payload: {\n partitionId: number;\n sourceNode: string;\n estimatedSize: number;\n };\n}\n\nexport interface MigrationChunkMessage {\n type: 'MIGRATION_CHUNK';\n payload: {\n partitionId: number;\n chunkIndex: number;\n totalChunks: number;\n data: Uint8Array;\n checksum: string;\n };\n}\n\nexport interface MigrationChunkAckMessage {\n type: 'MIGRATION_CHUNK_ACK';\n payload: {\n partitionId: number;\n chunkIndex: number;\n success: boolean;\n };\n}\n\nexport interface MigrationCompleteMessage {\n type: 'MIGRATION_COMPLETE';\n payload: {\n partitionId: number;\n totalRecords: number;\n checksum: string;\n };\n}\n\nexport interface MigrationVerifyMessage {\n type: 'MIGRATION_VERIFY';\n payload: {\n partitionId: number;\n success: boolean;\n checksumMatch: boolean;\n };\n}\n\nexport type MigrationMessage =\n | MigrationStartMessage\n | MigrationChunkMessage\n | MigrationChunkAckMessage\n | MigrationCompleteMessage\n | MigrationVerifyMessage;\n\n// ============================================\n// Consistency Levels (Task 04)\n// ============================================\n\nexport enum ConsistencyLevel {\n /** Wait for all replicas (owner + all backups) */\n STRONG = 'STRONG',\n /** Wait for majority (owner + N/2 backups) */\n QUORUM = 'QUORUM',\n /** Acknowledge after owner write only, background replication */\n EVENTUAL = 'EVENTUAL',\n}\n\nexport interface WriteOptions {\n consistency?: ConsistencyLevel;\n /** Replication timeout in ms */\n timeout?: number;\n}\n\nexport interface ReadOptions {\n consistency?: ConsistencyLevel;\n /** Read from backup if owner unavailable */\n allowStale?: boolean;\n /** Max acceptable lag in ms */\n maxStaleness?: number;\n}\n\n// ============================================\n// Replication Configuration (Task 04)\n// ============================================\n\nexport interface ReplicationConfig {\n defaultConsistency: ConsistencyLevel;\n /** Max queued operations (default: 10000) */\n queueSizeLimit: number;\n /** Operations per batch (default: 100) */\n batchSize: number;\n /** Batch flush interval in ms (default: 50) */\n batchIntervalMs: number;\n /** Ack timeout in ms (default: 5000) */\n ackTimeoutMs: number;\n /** Retries before marking node unhealthy (default: 3) */\n maxRetries: number;\n}\n\nexport const DEFAULT_REPLICATION_CONFIG: ReplicationConfig = {\n defaultConsistency: ConsistencyLevel.EVENTUAL,\n queueSizeLimit: 10000,\n batchSize: 100,\n batchIntervalMs: 50,\n ackTimeoutMs: 5000,\n maxRetries: 3,\n};\n\nexport interface ReplicationTask {\n opId: string;\n operation: unknown; // Will be typed more specifically in server\n consistency: ConsistencyLevel;\n timestamp: number;\n retryCount: number;\n}\n\nexport interface ReplicationLag {\n /** Current lag in ms */\n current: number;\n /** Average lag */\n avg: number;\n /** Maximum observed lag */\n max: number;\n /** 99th percentile lag */\n percentile99: number;\n}\n\nexport interface ReplicationHealth {\n healthy: boolean;\n unhealthyNodes: string[];\n laggyNodes: string[];\n avgLagMs: number;\n}\n\nexport interface ReplicationResult {\n success: boolean;\n ackedBy: string[];\n}\n\n// ============================================\n// Replication Protocol Messages (Task 04)\n// ============================================\n\nexport interface ReplicationMessage {\n type: 'REPLICATION';\n payload: {\n opId: string;\n operation: unknown;\n consistency: ConsistencyLevel;\n };\n}\n\nexport interface ReplicationBatchMessage {\n type: 'REPLICATION_BATCH';\n payload: {\n operations: unknown[];\n opIds: string[];\n };\n}\n\nexport interface ReplicationAckMessage {\n type: 'REPLICATION_ACK';\n payload: {\n opId: string;\n success: boolean;\n timestamp: number;\n };\n}\n\nexport interface ReplicationBatchAckMessage {\n type: 'REPLICATION_BATCH_ACK';\n payload: {\n opIds: string[];\n success: boolean;\n timestamp: number;\n };\n}\n\nexport type ReplicationProtocolMessage =\n | ReplicationMessage\n | ReplicationBatchMessage\n | ReplicationAckMessage\n | ReplicationBatchAckMessage;\n\n// ============================================\n// Constants\n// ============================================\n\nexport const PARTITION_COUNT = 271;\nexport const DEFAULT_BACKUP_COUNT = 1;\n"],"mappings":"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","names":["h","h","z","z","z","WriteConcern","PartitionState","ConsistencyLevel"]}
|