astriveone-db

Universal Database Engine For Everything. Install once. Use everywhere.
879
Install
npm install astriveone-db
Latest Version:1.2.0
License:MIT
Last Updated:Jun 30, 2026
Links: npm
Maintainer: althericoffc

astriveone-db

Universal Database Engine. One package, installed once.

npm version npm downloads license

npm install astriveone-db

Quick start

import { AstriveOne } from "astriveone-db";

const db = new AstriveOne();   // in-memory, zero config
await db.connect();

await db.set("users", { id: "001", username: "bayu" });
const user = await db.get("users", "001");
// { id: "001", username: "bayu" }

await db.close();

Drivers — what actually works where

Each driver has its own platform requirements. Choose the right one for your runtime.

memory — all platforms ✅

const db = new AstriveOne({ driver: "memory" });
Platform Works
Node.js ≥ 18 ✅
Bun ✅
Deno ✅
Browser ✅
Cloudflare Workers ✅
Vercel Edge ✅
React Native ✅

Data lives only in process memory. Zero persistence — use remote or pair with a server for shared/persistent access.


json — Node / Bun / Deno only ⚠️

const db = new AstriveOne({ driver: "json", path: "./data.json" });
Platform Works
Node.js ≥ 18 ✅
Bun ✅
Deno (with --allow-write) ✅
Browser ❌ No filesystem
Cloudflare Workers ❌ No filesystem
Vercel Edge ❌ No filesystem
AWS Lambda /tmp ⚠️ Ephemeral only — data lost on cold start
React Native ❌ No Node fs module

Calling db.connect() on a platform without a filesystem throws immediately with a clear error message rather than failing silently later.

Writes are crash-safe: data is written to a tmp file and atomically renamed, so a power loss mid-write cannot corrupt the database.


sqlite — Node 22+ / Bun ⚠️

const db = new AstriveOne({ driver: "sqlite", path: "./app.db" });
// or in-memory:
const db = new AstriveOne({ driver: "sqlite", path: ":memory:" });
Platform Works
Node.js ≥ 22 ✅ Uses built-in node:sqlite — no extra packages
Bun ✅
Node.js < 22 ❌ node:sqlite not available
Browser / Edge / RN ❌ No SQLite runtime

Uses Node 22's built-in node:sqlite module — zero extra npm dependencies. Native SQL transactions are fully supported (not a snapshot/rollback workaround):

await db.transaction(async (tx) => {
  await tx.update("accounts", "a1", { balance: 50 });
  await tx.update("accounts", "a2", { balance: 150 });
  // if anything throws → full ROLLBACK, no partial writes
});

// Direct SQL for complex queries:
const storage = new SQLiteStorage("./app.db");
const rows = storage.exec("SELECT COUNT(*) as c FROM __documents WHERE collection = ?", ["users"]);

remote — all platforms ✅

const db = new AstriveOne({
  mode: "remote",
  url: "https://db.example.com",
  apiKey: process.env.ASTRIVEONE_KEY,
});

An HTTP client over the AstriveOne-DB REST+WebSocket wire protocol. Works anywhere fetch is available (all modern JS runtimes). Start a server with await db.start() on your Node/Bun backend and point this at it from any other language or platform.


Planned — not yet implemented 🚧

Driver Status
postgres 🚧 Planned
mysql 🚧 Planned
mongo 🚧 Planned
redis 🚧 Planned

Calling connect() with any of these drivers throws a clear error that says exactly what is and isn't implemented. There is no driver that pretends to work but fails silently.


CRUD

// Insert — auto-generates id if omitted
await db.set("posts", { id: "p1", title: "Hello", views: 0 });
await db.set("posts", { title: "Auto ID" }); // id generated

// Read — returns null (not undefined, not an error) if missing
const post = await db.get("posts", "p1");

// Find with operators
const results = await db.find("posts", {
  where: {
    views: { $gte: 100 },                    // range
    category: { $in: ["tech", "design"] },   // in list
    title: { $contains: "guide" },           // string match
    draft: { $ne: true },                    // not equal
    published: true,                          // exact match
  },
  sort: { views: -1 },  // -1 desc, 1 asc
  limit: 20,
  offset: 0,
});

// Partial update — keeps fields not in patch
await db.update("posts", "p1", { views: 1 });

// Delete — returns false if document didn't exist
const deleted = await db.delete("posts", "p1");

Transactions

await db.transaction(async (tx) => {
  const sender = await tx.get("accounts", "alice");
  if (sender.balance < 100) throw new Error("insufficient funds");
  await tx.update("accounts", "alice", { balance: sender.balance - 100 });
  await tx.update("accounts", "bob",   { balance: bob.balance + 100 });
  // if anything throws, all writes are rolled back
});

Memory/JSON drivers use snapshot-and-rollback. SQLite driver uses native SQL BEGIN/COMMIT/ROLLBACK — guaranteed atomic by the database engine.


Realtime

// Watch a collection — fires on insert, update, delete
const stop = db.watch("messages", (event) => {
  console.log(event.type);       // "insert" | "update" | "delete"
  console.log(event.id);         // document id
  console.log(event.doc);        // new/updated document
  console.log(event.before);     // previous state (update/delete)
});

// Watch everything
const stopAll = db.watchAll((event) => {
  console.log(`${event.collection}/${event.id}: ${event.type}`);
});

// Custom pub/sub
db.subscribe("notifications", (payload) => console.log(payload));
db.emit("notifications", { text: "New message" });

// Stop watching
stop();

The realtime bus is a zero-dependency in-process event system (plain Map<string, Set<fn>>). No node:events, no EventEmitter — runs identically on Node, Bun, Deno, browsers, Cloudflare Workers, and React Native.


Authentication

// Register and login
await db.auth.register("bayu", "password123", ["admin"]);
const session = await db.auth.login("bayu", "password123");
console.log(session.token); // secure random token

// Verify and check roles
const verified = await db.auth.verify(session.token);
const isAdmin = db.auth.hasRole(verified, "admin");

// Logout (invalidates the token server-side)
await db.auth.logout(session.token);

// API keys for service-to-service auth
const key = await db.auth.createApiKey("my-bot", ["service"]);
await db.auth.verifyApiKey(key);
await db.auth.revokeApiKey(key);

External identity (OAuth integration)

This package does not perform OAuth flows (redirects, code exchange, provider API calls). That is your responsibility. Once you have verified an external identity, call:

// After YOU have verified the Google/GitHub/etc token and obtained the user's external id:
const session = await db.auth.createSessionFromExternalIdentity(
  "google",
  verifiedGoogleUserId,  // from Google's verified token payload
  { email: "bayu@gmail.com", name: "Bayu" }
);

If the user does not exist yet, a local record is created automatically. If they do, a new session is issued for the existing record.


Encryption at rest

// Requires an explicit, non-empty secret. encrypt: true alone is rejected.
const db = new AstriveOne({
  driver: "json",
  path: "./data.json",
  encrypt: { secret: process.env.DB_SECRET },  // must be explicit
});

Uses AES-256-GCM. The file on disk is completely unreadable without the secret. There is no hardcoded fallback key — passing an empty or whitespace-only secret throws immediately at connect().


Validation

db.defineSchema("users", {
  username: { type: "string", required: true, min: 3, max: 32 },
  email:    { type: "string", required: true, pattern: "^[^@]+@[^@]+$" },
  age:      { type: "number", min: 0, max: 120 },
  active:   { type: "boolean" },
});

// This throws before touching storage:
await db.set("users", { username: "ab" });
// AstriveOne-DB: validation failed for "users": "username" min length is 3

Built-in cache

await db.useCache({ ttl: 30_000, maxEntries: 1000 });

// Reads are cached — identical object reference on cache hit:
const a = await db.get("users", "u1");
const b = await db.get("users", "u1"); // same reference, from cache

// Cache is invalidated automatically on any write to the same collection
await db.update("users", "u1", { name: "Updated" });
const c = await db.get("users", "u1"); // fresh from storage

Security

// Rate limiting (token bucket per collection)
db.enableRateLimit(100, 60_000); // 100 ops per minute

// Audit log — every mutation recorded
const db = new AstriveOne({ audit: true });

// Backup / restore
await db.backup("./backups/2026-06-25.json");
await db.restore("./backups/2026-06-25.json");

Studio (visual admin dashboard)

const studio = await db.start({ port: 4848 });
// Prints:
// ╔══════════════════════════════════════════════╗
// ║           AstriveOne-DB v1.0.0               ║
// ╠══════════════════════════════════════════════╣
// ║  Status:   ONLINE                            ║
// ║  REST:     http://localhost:4848/api/db      ║
// ║  Studio:   http://localhost:4848/studio      ║
// ╠══════════════════════════════════════════════╣
// ║  Access Token:                               ║
// ║  astro_root_xxxxxxxxxxxxxxxxxxxxxxxxxxxx     ║
// ╚══════════════════════════════════════════════╝

// Tokens for sharing access:
const viewToken = await db.createToken("viewer", "read-only client", { expire: "24h" });
const editToken = await db.createToken("editor", "CI bot");
const list = await db.listTokens();
await db.revokeToken(list[0].id);
const rotated = await db.rotateToken(oldToken);

Examples

Discord bot

import { Client, GatewayIntentBits } from "discord.js";
import { AstriveOne } from "astriveone-db";

const db = new AstriveOne({ driver: "json", path: "./bot.json" });
await db.connect();

const client = new Client({ intents: [GatewayIntentBits.Guilds] });
client.on("interactionCreate", async (interaction) => {
  if (!interaction.isChatInputCommand()) return;
  if (interaction.commandName === "save") {
    await db.set("notes", { id: crypto.randomUUID(), userId: interaction.user.id, text: interaction.options.getString("text") });
    await interaction.reply({ content: "Saved ✓", ephemeral: true });
  }
});
client.login(process.env.DISCORD_TOKEN);

WhatsApp bot

import { Client } from "whatsapp-web.js";
import { AstriveOne } from "astriveone-db";

const db = new AstriveOne({ driver: "json", path: "./wa.json" });
await db.connect();
const client = new Client();
client.on("message", async (msg) => {
  if (msg.body.startsWith("!save ")) {
    await db.set("notes", { id: crypto.randomUUID(), from: msg.from, text: msg.body.slice(6) });
    msg.reply("Saved ✓");
  }
});
client.initialize();

License

MIT © althericoffcv — follow on GitHub

Related Packages

@xingyanpo/deplix

Deplix - A self-hosted CI/CD web panel for frontend project deployment. Install...

2,363
@takk/modelchain

Universal, drop-in, measurable LLM router with native streaming and tool calling...

918 1
ts-web-scraper

A powerful web scraper for both static and client-side rendered sites using only...

2,911,237 13
lazy-storage

Self-hosted realtime state store with offline sync, built on lazy-watch: keyed c...

5,479 0
@vinoskey524/oh-my-json

The zenith of JSON manipulation

1,974 1

Version History

Version Released License
1.2.0 MIT
1.1.0 MIT
1.0.1 MIT
1.0.0 MIT