UNPKG

@trap_stevo/star-vault

Version:

Deterministic data engine that eliminates query-time joins and enables normalized data execution. Architect secure, scalable, real-time systems with integrated sharding, encryption, and event-driven data flows. Manage hierarchical structures, execute adva

974 lines (771 loc) 118 kB
# 🚀 Star-Vault **Deterministic data engine that eliminates query-time joins and enables normalized data execution.** Architect secure, scalable, real-time systems with integrated sharding, encryption, and event-driven data flows. Manage hierarchical structures, execute advanced queries, and power enterprise systems, real-time dashboards, collaborative platforms, IoT infrastructures, and complex data-driven applications. Traditional systems force a fundamental tradeoff: - relational databases preserve structure but depend on runtime joins - NoSQL systems remove joins but sacrifice integrity through denormalization **Star-Vault introduces Hyper-Normalization™ — a model that resolves relationships deterministically within the storage and cache layers instead of reconstructing them during queries.** This model delivers: - near-constant-time access across normalized data structures - zero join planning or query optimization overhead - deterministic traversal across collections - real-time consistency without duplication Star-Vault integrates sharding, WAL, caching, and real-time events into a unified execution engine for high-performance, structure-driven systems. > ⚡ In Star-Vault, normalization stops costing performance and starts driving it. ## 📘 Table of Contents - [🌌 Features](#-features) - [⚙️ System Requirements](#️-system-requirements) ### API Overview - [📜 API Specifications](#-api-specifications) - [🔧 Constructor](#-constructor) - [🔐 authOptions (StarAuth Configuration)](#-authoptions-starauth-configuration) - [🔒 Lockout Configuration](#-lockout-configuration) - [Timing Heuristics](#-timing-heuristics) - [Password Management](#-password-management) - [🌍 Star Locator Configuration](#-star-locator-configuration) - [Stellar Login](#stellar-login) - [Hooks & Extensions](#hooks--extensions) - [Guest Session Configurations](#guest-session-configurations) - [Cleanup & Locking](#cleanup--locking) ### Core Engine - [📦 Core Methods](#-core-methods) - [📥 Import & Snapshot Methods](#-import--snapshot-methods) - [🧾 StarTransactions (WAL + Idempotency)](#-startransactions-wal--idempotency) ### Query System - [🔍 Query Engine](#-query-engine) - [⚙️ Return Modes](#️-return-modes) - [Execution Modes](#execution-modes) - [Methods](#methods) - [Examples](#examples) - [⚙️ Advanced Controls](#️-advanced-controls) - [📄 Cursor-Based Pagination](#️-cursor-based-pagination) - [Performance & Behavior](#performance--behavior) - [Developer Note](#developer-note) ### Hyper Normalization - [⚡️ Hyper-Normalization™](#️-hyper-normalization) - [🧬 Origin of Hyper-Normalization™](#-origin-of-hyper-normalization) - [🌌 Why Hyper-Normalization Matters](#-why-hyper-normalization-matters) - [🧩 User Display Example](#-example--the-user-display-case) - [Benchmark & Reproducibility](#benchmark--reproducibility) - [🚀 Performance Implications](#-performance-implications) ### Authentication - [🛡️ Authentication](#️-authentication) - [👤 User Registration & Authentication](#-user-registration--authentication) - [🛰️ Session Management](#-session-management) - [🔑 Password & Magic Link Recovery](#-password--magic-link-recovery) - [👥 Guest Account Management](#-guest-account-management) - [🔁 User Lifecycle Management](#-user-lifecycle-management) - [📊 User & Session Querying](#-user--session-querying) - [🧩 Internal Validation & Utility Methods](#-internal-validation--utility-methods) ### History + Logging - [🧭 Record History & Timeline](#-record-history--timeline) - [🧾 Auditing](#-auditing-history--timeline-reads) - [🪶 Debug & Developer Logging Options](#-debug--developer-logging-options) ### Logger - [🛰️ StarLogger](#-starlogger) - [🔧 Core Logger Methods](#-core-logger-methods) - [Write, System, and Audit Events](#write-system-and-audit-events) - [Recovery, Query & Maintenance](#recovery-query--maintenance) - [Rotation & Retention](#rotation--retention-built-in) ### Storage Layer - [📂 Starchive (Storage Layer)](#-starchive-storage-layer) - [⚙️ Starchive Configuration Modes](#️-starchive-configuration-modes) - [⚙️ Starchive Configurations](#️-starchive-configurations) - [📦 Starchive Core Methods](#-starchive-core-methods) - [✍️ Starchive Convenience Methods](#️-starchive-convenience-methods) - [🛰️ Remote Management Helpers](#-remote-management-helpers) - [🔏 Starchive Signing & Presigning](#-starchive-signing--presigning) - [🔏 Starchive Downloading](#-starchive-downloading) - [📜 Starchive Records](#-starchive-records) ### Event System - [🎧 Event Listening](#-event-listening) - [🌌 Collection & Path Matching](#-collection--path-matching) - [🌌 StarVault Events](#-starvault-events) ### Vacuum System - [🧽 Vacuum & Auto-Maintenance System](#-vacuum--auto-maintenance-system) - [⚙️ Automatic Vacuum Policy](#️-automatic-vacuum-policy) - [🪄 Methods](#-methods-1) - [🪶 Example](#-example) - [⚡ Auto-Vacuum Triggers](#️-auto-vacuum-triggers) - [📊 Metrics Example](#-metrics-example) ### Getting Started - [✨ Getting Started](#-getting-started) - [📦 Installation](#-installation) - [Basic Usage](#basic-usage) - [📈 Querying](#-querying) - [🎧 Listening to Changes](#-listening-to-changes) - [🌐 Wildcard Collection Queries](#-wildcard-collection-queries) - [👥 Registering Users](#-registering-users-guest-and-normal) - [📋 Listing Users and Sessions](#-listing-users-and-sessions) - [🔍 Quick Starchive Examples](#-quick-starchive-examples) - [✨ License](#-license) - [🚀 Transform Data into Action](#-transform-data-into-action) --- ## 🌌 Features - 🔐 **Optional Encryption** – Secure sensitive data at rest - ⚙️ **Sharded Storage Engine** – Efficiently scales writes across shards - 🧠 **In-Memory Caching** – High-speed read layer with `StarCache` - 📜 **Write-Ahead Logging** – Resilient logs with rotation and retention policies - 🔍 **Advanced Query Engine** – Chainable and expressive queries with filtering, search, sorting, and spatial support - 🚀 **Real-Time Event Emission** – Listen to data changes with fine-grained control - 🛡️ **Authentication Layer** – Optional handler to authorize every operation - 🌠 **Collection Wildcards** – Seamlessly operate across multiple collections --- ## ⚙️ System Requirements | Requirement | Version | |----------------|--------------------| | **Node.js** | ≥ 19.x | | **npm** | ≥ 9.x (recommended)| | **OS** | Windows, macOS, Linux | --- # 📜 API Specifications ## 🔧 Constructor Use these parameters when initializing `StarVault`. ```js new StarVault(dbPath, logPath, shardCount, maxLogSize, logRetention, options) ``` ### Core Parameters | Key | Description | Default | |---------------|------------------------------------------------------------------------------|--------------| | `dbPath` | Root directory for all collection data; each collection is stored in sharded files. | **Required** | | `logPath` | Directory where write-ahead logs (WAL) are stored for durability and replay. | **Required** | | `shardCount` | Number of shards used per collection. More shards improve concurrency. | `4` | | `maxLogSize` | Max size of each WAL file before rotation. Accepts values like `"100MB"`. | `"869MB"` | | `logRetention`| Duration to retain old WAL files. Accepts values like `"1w"` or `"30d"`. | `"1w"` | ### `options` Object | Key | Description | Default | |-------------------|-----------------------------------------------------------------------------|------------------------| | `enableEncryption`| Enables encryption for data at rest. | `false` | | `vaultPath` | Path to the vault metadata file used for encryption. | `"./star-vault.json"` | | `masterKey` | Master encryption key for vault encryption. Must securely generate/store.| `null` | | `authHandler` | Custom function that receives `clientAuth` and returns `true`/`false`. | `null` | | `authOptions` | Configuration object passed to internal `StarAuth` for authentication. | `{}` | | `auditHistory` | Turn on default auditing for history/timeline reads (writes entries to `audit.log`). Also toggle per call. | `false` | | `enableMesh` | Turn on StarMesh sync layer. | `false` | | `storageOptions` | Configuration object passed to the main storage engine for controlling low-level storage behavior, metrics flushing, shard hashing, and the automatic, idle-aware background compaction scheduler. | `{}` | | `meshOptions` | Options passed to `StarMesh` when `enableMesh` = `true`. | `{}` | | `starchive` | Configuration for the `Starchive` subsystem (local and remote file management). | `{}` | | `queryMetrics` | Query metrics configuration object or `false` to disable metrics. | `{ enabled : true }` | | `debugOptions` | Fine-grained developer logging controls for internal tracing (see below). | `{ all flags default to true }` | | `dirMode` | UNIX permission mode for directories (e.g., `0o700`). | `0o700` | | `fileMode` | UNIX permission mode for files (e.g., `0o600`). | `0o600` | --- ## storageOptions (Main Storage Configuration) These options control low-level storage behavior, metrics flushing, shard hashing, and the automatic, idle-aware background compaction scheduler. | Key | Type | Description | Default | | ----------------------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | | `idxFlushIntervalMs` | `number` | Interval (ms) for flushing pending `.idx` writes when `idxSyncMode` is set to `interval`. Lower values improve durability and cross-process visibility; higher values reduce IO overhead. Minimum enforced value is `10`. | `50` | | `idxSyncMode` | `"interval" \| Controls how `.idx` files are synced to disk. `"interval"` batches fsync calls based on `idxFlushIntervalMs`; `"always"` fsyncs on every index write for maximum durability at the cost of IO. | `"always"` | | `onWriteError` | `function` | Optional callback invoked when a write fails prior to persistence (for example, due to serialization failure). Receives the error and contextual metadata (`collection`, `id`, `value`). The write skips persistence and creates no pending or on-disk state. | | `metricsFlushIntervalMs` | `number` | Interval (ms) for flushing in-memory storage metrics (`fileBytes`, `liveBytes`, update counters) to disk. Lower values increase durability; higher values reduce IO. | `50` | | `shardHashFn` | `(id : string) => number` | Optional custom hash function used to determine shard placement. Return value is modulo-ed by shard count. | `undefined` | | `compactionEnabled` | `boolean` | Enable or disable background compaction entirely. Manual `vacuum*()` APIs still work when disabled. | `true` | | `compactionIdleMs` | `number` | Minimum time (ms) a collection must be idle (no writes) before it becomes eligible for background compaction. | `2500` | | `compactionCooldownMs` | `number` | Cooldown period (ms) after a collection is compacted before it may be compacted again by the scheduler. | `60000` | | `compactionTickMs` | `number` | Scheduler tick interval (ms). Determines how often pending compaction work is evaluated. | `200` | | `compactionMaxCollectionsPerTick` | `number` | Maximum number of collections that may be compacted in a single scheduler tick. | `1` | | `compactionMaxShardsPerCollectionPerTick` | `number` | Maximum number of shards compacted per collection per tick. Keeps pauses small and predictable. | `1` | --- ## 🔐 authOptions (StarAuth Configuration) Pass this object under the `options.authOptions` key when creating your `StarVault` instance. ### Collection Settings | Key | Description | Default | |----------------------|--------------------------------------------|---------------------| | `starAuthEnabled` | Global switch that controls whether the StarAuth subsystem activates. Set to `false` to disable authentication features entirely while keeping vault access open. | `true` | | `collection` | User collection name | `"auth-users"` | | `sessionCollection` | Session tracking collection | `"auth-sessions"` | | `resetCollection` | Password reset token collection | `"auth-resets"` | | `lockCollection` | Lockout state tracking collection (per account/IP/UA). | `"auth-locks"` | | `stellarCollection` | Magic link / code token collection | `"stellar-auths"` | ### Session Behavior These options control the creation, validation, and protection of sessions against brute-force attacks. | Key | Description | Default | |----------------------------|------------------------------------------------------------------------------|--------------------------| | `tokenExpiry` | Lifetime of each session token in seconds. | `3600` (1 hour) | | `sessionValidationFields` | Fields compared on every request to detect hijacking (e.g. IP, fingerprint). | `["ip", "fingerprint"]` | | `strictSessionValidation` | If `true`, any mismatch in validation fields invalidates the session. | `true` | | `enableSuspiciousCheck` | If `true`, compares geo/IP against recent sessions to flag anomalies. | `true` | | `sessionPolicy` | Session strategy: `"default"` (allow many), `"strict"` (1 active max), `"replace"` (replace old). | `"default"` | --- ### 🔒 Lockout Configuration Controls the tracking, weighting, and escalation behavior of failed login attempts. All options go inside `options.authOptions.lockout`. | Key | Description | Default | |--------------------|-------------------------------------------------------------------------------------------------|------------------------| | `strategy` | Lockout algorithm: `"fixed"`, `"slidingWindow"`, or `"exponential"`. | `"fixed"` | | `scopes` | Dimensions to track failures against: `["account", "ip", "ipua"]`. | `["account", "ipua"]` | | `maxAttempts` | Failures allowed before triggering lock. | `5` | | `baseDuration` | Base lockout duration in ms. | `15 * 60 * 1000` | | `maxDuration` | Max lockout duration in ms (for exponential strategy). | `24 * 60 * 60 * 1000` | | `minDuration` | **Absolute minimum** lock duration in ms (applies to all strategies; jitter won’t go below this). | `30 * 1000` | | `jitterDuration` | Random jitter ± ms added to lock duration. | `15 * 1000` | | `decayDuration` | Auto-decay failures if no attempts within this duration. | `30 * 60 * 1000` | | `windowDuration` | For `slidingWindow`, the rolling time window in ms. | `10 * 60 * 1000` | | `windowThreshold` | For `slidingWindow`, number of failures in the window that triggers lock. | `7` | | `windowGrowth` | For `slidingWindow`, how lock duration grows when over threshold: `"none" \| "linear" \| "exponential"`. | `"none"` | | `windowGrowthFactor` | For `slidingWindow: "exponential"` — multiplier per extra failure over threshold. | `2` | | `windowGrowthStep` | For `slidingWindow: "linear"` — extra ms per extra failure over threshold. | `baseDuration / 2` | | `captchaAfter` | Number of failures after which a CAPTCHA challenge is required. | `null` | | `otpAfter` | Number of failures after which an OTP challenge is required. | `null` | | `captchaVerifier` | Function `(req) => boolean` to validate CAPTCHA. | `null` | | `otpVerifier` | Function `({ email, code }) => boolean` to validate OTP. | `null` | | `onLock` | Callback `(info) => void` fired when a lock is applied. | `null` | | `onUnlock` | Callback `(info) => void` fired when a lock is cleared. | `null` | | `onChallenge` | Callback `(info) => void` fired when a CAPTCHA/OTP challenge is required. | `null` | | `notifyLock` | Optional notifier `(info) => void` for alerts/logging. | `null` | | `bypassed` | Function `(req) => boolean` to completely bypass lockout logic for trusted requests. | `null` | --- #### Timing Heuristics `options.authOptions.lockout.timingHeuristics` adds intelligence by classifying failures as bursts, normal, or human-like delays. | Key | Description | Default | |-----------------------|-----------------------------------------------------------|----------| | `enabled` | Enable timing heuristics. | `true` | | `burstDetectionDuration` | Attempts within this ms count as a burst (weighted more). | `3000` | | `humanDetectionDuration` | Attempts slower than this ms count as human/grace. | `45000` | | `maxConsiderDuration` | Ignore intervals longer than this ms. | `600000` | | `burstWeight` | Weight applied to burst failures. | `2.0` | | `normalWeight` | Weight applied to normal failures. | `1.0` | | `graceWeight` | Weight applied to grace (slow) failures. | `0.0` | | `emaAlpha` | Alpha for exponential moving average of attempt intervals. | `0.3` | | `decayOnGrace` | Whether to decay counters when a grace attempt is detected.| `true` | | `decayStep` | How many failures to subtract during a grace decay. | `1` | | `minFailures` | Clamp: minimum number of failures tracked. | `0` | | `maxFailures` | Clamp: maximum number of failures tracked. | `9999` | --- #### Example Fixed Lockout Config ```js authOptions: { lockout: { strategy: "fixed", scopes: ["account", "ipua"], maxAttempts: 5, // lock after N total failures baseDuration: 15 * 60 * 1000, // fixed lock duration (with jitter) minDuration: 30 * 1000, jitterDuration: 15 * 1000, // desync scripted retries decayDuration: 30 * 60 * 1000, // clear counters after idle period // Optional human gates captchaAfter: 3, otpAfter: null, captchaVerifier: async (req) => verifyCaptcha(req.body.token), // Heuristics amplify bursts, forgive human pace timingHeuristics: { enabled: true, burstDetectionDuration: 3000, humanDetectionDuration: 45000, burstWeight: 2.0, normalWeight: 1.0, graceWeight: 0.0, emaAlpha: 0.3, decayOnGrace: true, decayStep: 1, minFailures: 0, maxFailures: 9999 }, onLock: (info) => console.log("LOCKED", info), onUnlock: (info) => console.log("UNLOCKED", info), onChallenge: (info) => console.log("CHALLENGE", info), bypassed: (req) => false } } ``` 👉 When to use: Simple setups where predictability matters. Good for smaller apps, prototypes, or admin dashboards where you want consistent enforcement. --- #### Example Sliding Window Lockout Config ```js authOptions: { lockout: { strategy: "slidingWindow", scopes: ["account", "ipua"], windowDuration: 10 * 60 * 1000, windowThreshold: 7, baseDuration: 60 * 1000, minDuration: 30 * 1000, maxDuration: 24 * 60 * 60 * 1000, jitterDuration: 15 * 1000, windowGrowth: "exponential", windowGrowthFactor: 2, // windowGrowthStep: 30 * 1000, // if using "linear" // Optional Human gates captchaAfter: 3, otpAfter: null, captchaVerifier: async (req) => verifyCaptcha(req.body.token), // Heuristics amplify bursts, forgive human pace timingHeuristics: { enabled: true, burstDetectionDuration: 2000, humanDetectionDuration: 45000, burstWeight: 2.5, normalWeight: 1.0, graceWeight: 0.0, emaAlpha: 0.35, decayOnGrace: true, decayStep: 1, minFailures: 0, maxFailures: 9999 }, onLock: (info) => console.log("LOCKED", info), onUnlock: (info) => console.log("UNLOCKED", info), onChallenge: (info) => console.log("CHALLENGE", info), bypassed: (req) => false } } ``` 👉 When to use: Ideal for games and consumer apps. It’s forgiving to legit players (counters decay naturally) but still stops brute-force bursts quickly. --- #### Example Exponential Lockout Config ```js authOptions: { lockout: { strategy: "exponential", scopes: ["account", "ipua"], maxAttempts: 5, baseDuration: 30 * 1000, minDuration: 30 * 1000, maxDuration: 24 * 60 * 60 * 1000, jitterDuration: 10 * 1000, captchaAfter: 3, otpAfter: 5, captchaVerifier: async (req) => verifyCaptcha(req.body.token), otpVerifier: async ({ email, code }) => verifyOtp(email, code), onLock: (info) => console.log("LOCKED", info), onUnlock: (info) => console.log("UNLOCKED", info), timingHeuristics: { enabled: true, burstWeight: 3.0, graceWeight: 0.0, emaAlpha: 0.4 } } } ``` 👉 When to use: Best for high-security apps, admin portals, or payment flows. Makes repeated brute-forcing impractical, but can be harsh for end-users if tuned too aggressively. --- #### 🧭 Legacy Lockout These highlight the original “simple” lockout knobs. They remain in place for backward compatibility and apply **in addition** to the modern `authOptions.lockout` logic. | Key | Description | Default | |---------------------|----------------------------------------------------------------------------------------------------------|----------------------------| | `lockoutDuration` | **(Legacy)** Fixed lock duration (ms) after too many failed logins. | `900000` (15 minutes) | | `maxLoginAttempts` | **(Legacy)** Number of failed attempts before the legacy lockout triggers. | `5` | **How they interact:** - On every failed login, the modern lockout mechanism (if configured) evaluates first. - The legacy counters also increment and, if `failedAttempts >= maxLoginAttempts`, a fixed lock of `lockoutDuration` is applied. - This ensures older deployments keep their original behavior while you migrate to the new model. **Recommendation:** - Prefer the new `authOptions.lockout` settings for fine-grained control. - If you want the legacy lockout to *rarely* affect users, set a **very large** `maxLoginAttempts` (e.g., `1_000_000`) and leave modern lockout to do the real work. **Example (modern lockout active, legacy effectively neutralized):** ```js authOptions: { // Modern lockout (recommended) lockout: { strategy: "exponential", scopes: ["account", "ipua"], maxAttempts: 5, baseDuration: 15 * 60 * 1000, // 15 minutes maxDuration: 24 * 60 * 60 * 1000 // 24 hours // ...captcha/otp/timingHeuristics, etc. }, maxLoginAttempts: 5, lockoutDuration: 15 * 60 * 1000 } ``` --- ### Password Management | Key | Description | Default | |----------------------|----------------------------------------------------------------------------------------------|--------------------------------------------| | `passwordRequirements` | Object defining the password policy | `{ minLength: 8, requireLetter: true, requireNumber: true, requireSymbol: false }` | | └ `minLength` | Minimum number of characters required | `8` | | └ `requireLetter` | Requires at least one letter (a-z or A-Z) | `true` | | └ `requireNumber` | Requires at least one numeric digit (0-9) | `true` | | └ `requireSymbol` | Requires at least one symbol (e.g., `!@#$%^&*`) | `false` | | └ `customValidator` | Optional custom function `(password) => boolean` for advanced password checks | `null` | | `lockingCombinations` | Password hash complexity | `10` | ### 🌍 Star Locator Configuration | Key | Description | Default | |---|---|---| | `enableGeo` | Enable geo lookups. | `false` | | `enableReverseGeo` | Reverse geocode coordinates. | `false` | | `enableGeoDebug` | Log provider results. | `false` | | `geoProviders` | Extra providers `(ip, {signal}) => result`. | `[]` | | `ipgeolocationKey` | ipgeolocation.io key. | `null` | | `ipinfoToken` | ipinfo.io token. | `null` | | `nominatimUserAgent` | UA for Nominatim reverse geo. | `"StarAuth/1.0 (star-vault@sclpowerful.com)"` | | `googleMapsKey` | Google Geocoding key. | `null` | | `mapboxToken` | Mapbox token. | `null` | | `geoCacheTtlMs` | Cache TTL. | `600000` | | `geoDeadlineMs` | Deadline per lookup. | `3000` | | `geoTimeoutMs` | Timeout per provider. | `2500` | | `geoScoreOk` | Early-accept score threshold. | `5` | | `geoMaxConcurrency` | Max concurrent calls. | `8` | #### Example `geo` Object in Sessions ```js geo: { requestIP: "203.0.113.45", ip: "203.0.113.45", city: "City", region: "Region", country: "Country", continent: "Continent", org: "Org / ASN", isp: "ISP", loc: "12.3456,-98.7654", timezone: "Area/City", postal: "ZIP", flag: "🌍", confidence: 0.83, geoAddress: "123 Main St, Example City, Country" } ``` #### Custom Provider Registration ```js const vault = new StarVault(dataDir, logDir, 4, "869MB", "1w", { authOptions: { enableGeo: true, enableReverseGeo: true, ipinfoToken: process.env.IPINFO_TOKEN, geoProviders: [ async function customProvider(ip, { signal }) { return { city: "Custom City", country: "Customland" }; } ] } }); ``` ### Stellar Login | Key | Description | Default | |---------------------------|-------------------------------------------------|-----------------| | `stellarRequestCooldown`| Minimum delay between stellar requests | `60000` (1 min) | | `generateStellarCode` | Function to generate a stellar numeric code | 6-digit default | ### Hooks & Extensions | Key | Description | |----------------------|------------------------------------------------------| | `onSuspiciousSession`| `(currentSession, pastSession) => void` | | `handleHijack` | `(session, field, expected, actual) => void` | | `onCleanup` | `({ result, timestamp, vaultID }) => void` | | `tagSession` | `(session, userData) => string[]` | ### Guest Session Configurations | Key | Description | Default | |-----------------------------|-----------------------------------------------------------------------------|----------------------------------| | `allowGuestSessions` | Enables or disables guest session support. | `true` | | `guestInactivityThreshold` | Duration of inactivity (in ms) before considering a guest account stale. | `7 * 24 * 60 * 60 * 1000` (1w) | | `cleanupGuestInterval` | Interval (in ms) to check for inactive guest accounts. | `5 * 60 * 1000` (5m) | | `guestActivityTrackers` | Array of custom functions to execute on guest activity updates. | `[]` | | `generateGuestID` | Function to generate guest user IDs. | `() => "guest-" + UUID` | ### Cleanup & Locking | Key | Description | Default | |--------------------------------|------------------------------------------------------|-------------| | `vaultID` | ID for this vault instance | `null` | | `autoCleanupInterval` | How often to auto-clean expired tokens | `null` | | `expiredSessionCleanupInterval` | Interval for cleaning expired sessions | `null` | | `detachedTimers` | Controls whether background cleanup timers remain linked to the process. Set to `false` to keep timers active until completion (useful for long-running or graceful shutdown scenarios). | `true` | | `cleanupExpiredTokensActionInfo` | Metadata for cleanup activity | `{}` | | `cleanupExpiredTokensClientAuth` | Auth context used for cleanup calls | `null` | | `cleanupExpiredSessionsActionInfo` | Metadata for session cleanup | `{}` | | `cleanupExpiredSessionsClientAuth` | Auth context used during session cleanup | `null` | --- ## 📦 Core Methods The primary database interaction methods. | Method | Description | Sync/Async | |--------|-------------|------------| | `create(collection, data, actionInfo = {}, clientAuth = null)` | Creates a new record in the specified collection. Returns the created record object. | ✅ Sync | | `update(collection, id, updates, actionInfo = {}, clientAuth = null)` | Updates an existing record by ID. Setting record data properties to undefined removes them respectively. Returns the updated record. Throws error if not found. | ✅ Sync | | `unset(collection, id, dotPaths = [], actionInfo = {}, clientAuth = null)` | Removes specific nested fields using dot notation (e.g., "profile.stats.xp"). Returns updated record. | ✅ Sync | | `deleteCollection(collection, actionInfo = {}, clientAuth = null)` | Deletes an entire collection. Returns `{ wholeCollection: true, deleted: true/false }`. | ✅ Sync | | `deleteRecord(collection, id, actionInfo = {}, clientAuth = null)` | Deletes a specific record by ID. Returns `{ id, deleted: true/false }`. | ✅ Sync | | `deleteMany(collection, ids = [], actionInfo = {}, clientAuth = null)` | Deletes many records efficiently (shard-grouped delete). Returns `{ requested, deleted, shardsTouched }`. | ✅ Sync | | `delete(collection, id, actionInfo = {}, clientAuth = null)` | Soft-deletes a record by filtering it out and overwriting the collection. Returns `{ id, deleted: true }`. | ✅ Sync | | `softDelete(collection, id, { reason = "soft-delete", deletedBy = null } = {}, actionInfo = {}, clientAuth = null)` | Mark a record as deleted **without removing it**. Sets flags: `deleted: true`, `deletedAt`, `deletedReason`, `deletedBy`. Emits `update`. Returns `{ id, softDeleted: true, at, reason, deletedBy }`. | ✅ Sync | | `restore(collection, id, { restoredBy = null } = {}, actionInfo = {}, clientAuth = null)` | Reverse a prior soft delete. Clears `deleted*` flags and sets `restoredAt`, `restoredBy`. Emits `update`. Returns `{ id, restored: true, at, restoredBy }`. | ✅ Sync | --- ### 🧾 StarTransactions (WAL + Idempotency) Star-Vault handles **multi-record transactions** with staged commits, WAL logging, and per-step idempotency. #### Core Traits - Logs each `TX-BEGIN` and `TX-COMMIT` before writing data. - Replays committed groups safely after crash or restart. - Keeps uncommitted changes isolated until commit. #### Transaction Methods ```js // High-level helper const { transactionID, result } = await vault.transact({ type: "transfer" }, async (t) => { await t.update("accounts", "A", { balance: v => v - 100 }); await t.update("accounts", "B", { balance: v => v + 100 }); await t.create("ledger", { from: "A", to: "B", amount: 100, ts: Date.now() }); return "ok"; }); // Manual flow const tx = await vault.begin({ type: "batch-import" }); await tx.create("users", { id: "u1", name: "Nova" }); await tx.softDelete("posts", "p-123", { reason: "policy", deletedBy: "mod-9" }); await tx.restore("posts", "p-123", { restoredBy: "mod-9" }); await tx.commit(); // or await tx.abort("reason"); ``` | Context | Method | Purpose | Sync/Async | |----------|---------|----------|-------------| | vault | `transact(actionInfo, fn)` | Open txn, run `fn(tx)`, commit on success, abort on failure. Returns `{ transactionID, result }`. | ⚙️ Async | | vault | `begin(actionInfo?, clientAuth?)` | Start txn and return handle `{ id, create, update, unset, deleteRecord, softDelete, restore, commit, abort }`. | ⚙️ Async | | tx | `create(collection, data, actionInfo?, clientAuth?)` | Stage record creation. | ⚙️ Async | | tx | `update(collection, id, updates, actionInfo?, clientAuth?)` | Stage record update; supports function deltas `v => v - 50`. | ⚙️ Async | | tx | `unset(collection, id, dotPaths = [], actionInfo?, clientAuth?)` | Stage removal of nested fields. | ⚙️ Async | | tx | `deleteRecord(collection, id, actionInfo?, clientAuth?)` | Stage hard deletion. | ⚙️ Async | | tx | `softDelete(collection, id, { reason?, deletedBy? } = {}, actionInfo?, clientAuth?)` | Stage soft deletion (flags only). | ⚙️ Async | | tx | `restore(collection, id, { restoredBy? } = {}, actionInfo?, clientAuth?)` | Stage record restoration. | ⚙️ Async | | tx | `commit(actionInfo?)` | Apply staged ops, refresh cache, emit events, seal WAL. | ⚙️ Async | | tx | `abort(reason = "manual")` | Discard staging and log `TX-ABORT`. | ⚙️ Async | #### Idempotency and WAL - Each step logs internal `transactionID` and deterministic `idempotencyKey`. - Steps replay safely on crash recovery; duplicates ignored. #### Example Flow ```js await vault.transact({ actor: "u42" }, async (tx) => { await tx.create("users", { id: "42", name: "Orion" }); await tx.update("profiles", "42", { visits: v => v + 1 }); await tx.softDelete("sessions", "s-23", { reason: "expired", deletedBy: "system" }); }); ``` --- ## 🔍 Query Engine The **Query Engine** powers Star-Vault’s adaptive data traversal and filtering system — providing a fully chainable, composable query builder with deterministic caching and automatic mode optimization. ### Overview ```js vault.query("collection") .whereRecord("id", "value") // Filter by root record metadata .where({ key : "value" }) // Filter by record data fields .search("field", "text") // Text search within a field .recent("timestamp", "7d") // Filter records from last 7 days .near("location", { lat : 0, lng : 0 }, 50) // Geospatial radius filter .sort({ name : 1 }) // Sort ascending (1) or descending (-1) .select(["id", "name"]) // Return specific fields only .limit(10) // Limit number of results .offset(0) // Skip first N results .page({ limit : 10, after : null }) // Cursor-based pagination alternative .filterBy(record => record.active) // Apply custom JS-level filter .callback(row => { row._scanned = true }) // Optional pre-execution side effect .return("data") // (Optional) Return only the record data .execute(false, "auto"); // Execute with collection matching and mode control ``` --- ### ⚙️ Return Modes | Method | Description | Default | |---------|-------------|----------| | **`return("record")`** | Return the full record object including metadata (`{ id, data, timestamp, ... }`). | ✅ Default | | **`return("data")`** | Return only the user data (`record.data`). | | | **`returnFull()`** | Shorthand for `.return("record")`. | ✅ | --- ### Execution Modes | Mode | Description | Ideal Use Case | |------|--------------|----------------| | **auto** | Automatically selects the best execution path depending on query shape. Defaults to `hyper` when possible. | General queries | | **hyper** | Direct single-record retrieval path. Bypasses iteration and uses direct cache lookup for deterministic key-value equality filters. | Exact key lookups (`id`, `userID`, etc.) | | **default** | Standard streaming scan with limit/offset early cutoffs. Supports progressive paging and partial reductions. | Sequential or paginated scans | > ⚙️ Star-Vault automatically promotes `auto` queries to `hyper` when the filter is deterministic (single key-value pair + limit ≤ 1). --- ### Methods | Method | Description | Sync/Async | |--------|--------------|------------| | `query(collection, actionInfo?)` | Begin a query on the specified collection. Returns a chainable QueryBuilder. | ✅ Sync | | `whereRecord(criteria)` | Filter by root record metadata (`record.id`, etc.). | ✅ Sync | | `where(criteria)` | Filter by record data key-value pairs. | ✅ Sync | | `search(field, text)` | Text search (substring or tokenized) in a specific field. | ✅ Sync | | `recent(field, duration)` | Filter by recency, e.g. `"7d"`, `"30m"`. | ✅ Sync | | `near(field, center, radius)` | Filter spatially near a `{ lat, lng }` point. | ✅ Sync | | `sort(criteria)` | Sort results ascending (`1`) or descending (`-1`). | ✅ Sync | | `select(fields)` | Choose fields to include in the output. | ✅ Sync | | `limit(number)` | Restrict result count. | ✅ Sync | | `offset(number)` | Skip first N results for pagination. | ✅ Sync | | `page(options)` | Enables cursor-based pagination with deterministic ordering. Returns `{ items, nextCursor }` when calling execute(). | ✅ Sync | | `filterBy(fn)` | Apply a custom filter function to each record. | ✅ Sync | | `callback(fn)` | Add a hook or side effect before result finalization. | ✅ Sync | | `configureAutoIndex(options)` | Enables or tunes adaptive auto-indexing for queries that repeatedly miss fast paths. | ✅ Sync | | `return(mode)` | Control whether queries return `"record"` (full record) or `"data"` (just data). | ✅ Sync | | `returnFull()` | Explicitly reset return mode to `"record"`. | ✅ Sync | | `execute(exactCollection = false, executionMode = "auto")` | Execute query. If `exactCollection = true`, restrict to the specified collection only. | ✅ Sync | | `getByID(collection, id, actionInfo?)` | Retrieve a record directly by primary key. | ✅ Sync | | `getManyByID(collection, ids, options?)` | Retrieve multiple records by an array of primary keys, **preserving input order**. | ✅ Sync | | `range(min, max)` | Static helper to produce inclusive numeric ranges. | ✅ Sync | --- ### Examples #### 🔸 Full Records (Default) const orders = vault.query("orders") .where({ status : "shipped" }) .execute(); // Returns [{ id, data, timestamp, ... }] #### 🔸 Data-Only View const orders = vault.query("orders") .where({ status : "shipped" }) .return("data") .execute(); // Returns only record.data objects #### 🔸 Revert to Full Records const orders = vault.query("orders") .where({ status : "shipped" }) .returnFull() .execute(); --- #### 🔸 Auto Mode (Adaptive) ```js const user = vault.query("users") .where({ id : "u-1" }) .select(["name", "email"]) .execute(false, "auto")[0]; ``` Automatically selects `hyper` mode due to deterministic equality filter and small result limit. --- #### 🔸 Hyper Mode (Accelerated) ```js const user = vault.query("users") .where({ id : "u-1" }) .limit(1) .execute(false, "hyper")[0]; ``` Uses a direct reference lookup path through **StarCache** for **O(1)** deterministic retrieval. --- #### 🔸 Default Mode (Streaming Scan) ```js const users = vault.query("users") .where({ active : true }) .offset(100) .limit(50) .sort({ createdAt : -1 }) .execute(false, "default"); ``` Uses a sequential scan with **early cutoff** logic for predictable pagination over large datasets. --- #### 🔸 **Many-by-ID (order-preserving)** ```js const [ u1, u5, u3 ] = vault.getManyByID("users", ["u-1", "u-5", "u-3"]); ``` --- #### 🔸 Advanced Example (Custom Logic & Hooks) ```js vault.query("orders") .where({ status : "pending" }) .filterBy(order => order.total > 100) .callback(order => { order.checked = true }) .select(["id", "total", "status"]) .limit(5) .execute(false, "auto"); ``` > The callback() hook works best for small, customized post-processing operations or live UI effects before final emission. --- ### ⚙️ Advanced Controls #### `configureAutoIndex(options)` Enable or tune adaptive auto-indexing for queries that repeatedly miss fast paths. **Options** - `enabled : boolean` — Turn auto-indexing on/off. - `missThreshold : number` — How many cache/scan “misses” trigger an index build. - `windowMs : number` — Rolling time window for counting misses. - `maxConcurrentBuilds : number` — Cap background index builds. - `lazyMaxScan : number` — Upper bound for a “lazy” scan before promoting to an index. **Example** ```js vault.query("orders") .configureAutoIndex({ enabled : true, missThreshold : 8, windowMs : 60_000, maxConcurrentBuilds : 2, lazyMaxScan : 50_000 }) .where({ status : "pending" }) .sort({ createdAt : -1 }) .limit(100) .execute(false, "auto"); ``` **Notes** - `configureAutoIndex()` affects only the current query builder chain. - The adaptive indexer monitors repetitive scans and builds background indexes once thresholds reach their limits. - Star-Vault manages concurrency and I/O impact internally—no manual worker orchestration required. - Auto-indexing integrates with StarCache and never blocks live queries. - You can disable it in lightweight or memory-constrained deployments without affecting correctness. --- ### 📄 Cursor-Based Pagination Star-Vault provides **deterministic, cursor-based pagination** for stable traversal across large datasets. Unlike offset-based pagination, cursor pagination: - avoids skipped/duplicated records under concurrent writes - maintains stable ordering - scales efficiently for large collections --- #### Basic Usage ```js const page1 = vault.query("users") .where({ country : "US" }) .page({ limit : 5 }) .execute(); console.log(page1.items); console.log(page1.nextCursor); ``` --- #### Fetching the Next Page ```js const page2 = vault.query("users") .where({ country : "US" }) .page({ limit : 5, after : page1.nextCursor }) .execute(); ``` --- #### Return Shape ```js { items : [ /* records */ ], nextCursor : "cursor-string-or-null" } ``` | Field | Description | |--------------|-------------| | `items` | Array of records (or data depending on return mode) | | `nextCursor` | Cursor string for the next page, or `null` if no more results | > ℹ️ Pagination changes the return type of `.execute()` from an array to a `{ items, nextCursor }` object. --- #### Cursor Behavior - `nextCursor = null` → no more pages - Passing `after : cursor` resumes from the last record of the previous page - Cursor encoding is **opaque and versioned internally** --- #### Example — Full Pagination Flow ```js let cursor = null; do { const page = vault.query("users") .where({ country : "US" }) .page({ limit : 5, after : cursor }) .execute(); console.log(page.items); cursor = page.nextCursor; } while (cursor); ``` --- #### ⚙️ Deterministic Ordering Pagination relies on Star-Vault’s **deterministic ID ordering**, ensuring: - stable page boundaries - no duplication across pages - no missing records during traversal > ⚠️ Important: Do not mutate record IDs or manually inject non-deterministic IDs if you rely on pagination stability. --- ### Performance & Behavior - **Adaptive Execution Pathing** — chooses optimal mode based on filter complexity and limit count. - **Cache-Aware Traversal** — leverages in-memory record handles for active collections. - **Early-Cutoff Scanning** — truncates scan loops when limits are reached to reduce latency. - **Geospatial and Temporal Filtering** — supports proximity, duration, and time-based conditions natively. - **Lightweight Chaining** — each query stage mutates minimal state, maintaining sub-millisecond builder overhead. --- ### Developer Note Query Engine provides direct low-level access to **StarVault's compositional access model**. When combined with **Hyper-Normalization™**, queries can achieve sub-millisecond lookups even across multi-collection normalized schemas. --- ## ⚡️ Hyper-Normalization™ Star-Vault introduces **Hyper-Normalization™**, a revolutionary data-modeling paradigm that unlocks the **highest logical purity** of data — with **near-zero performance penalties**. ### Definition Hyper-Normalization™ (noun)  /ˈhaɪ.pər ˌnɔr.mə.laɪˈzeɪ.ʃən/ A data-modeling paradigm introduced by Steven Compton in 2025 (Star-Vault) that implements physical-path normalization, eliminating runtime join planning through deterministic reference resolution and achieving near-constant-time cross-collection traversal under defined consistency and locality models. _First published: 2025-11-04_ _Coined and defined by Steven Compton, creator of Star-Vault._ --- ### 🧬 Origin of Hyper-Normalization™ **Before Star-Vault**, no database truly achieved runtime-lev