Skip to content

Release Notes (Developer Guide) โ€‹

What changed in recent FLASH releases and how to adopt it in your apps.

Current version: 1.0.0 ยท Tests: 155/155


v1.0.0 โ€” npm @moaaz-i/flash-db โ€‹

npm rejected the unscoped name flash-db (too similar to the existing flashdb package). The official npm name is @moaaz-i/flash-db.

bash
npm install @moaaz-i/flash-db
js
import { FlashClient } from "@moaaz-i/flash-db";

v1.3.2 โ€” Default Buffer Pipeline โ€‹

Summary โ€‹

The engine now keeps records as FlashBinary Buffers end-to-end. The SDK still accepts and returns plain JavaScript objects โ€” conversion happens once at the client boundary.

Your app (object) โ†’ encryptToBuffer() โ†’ Buffer โ†’ WAL / SSTable
WAL / SSTable โ†’ Buffer โ†’ decryptFromBuffer() โ†’ Your app (object)

New APIs โ€‹

APIWherePurpose
client.encryptToBuffer(doc)FlashClientPlain doc โ†’ encrypted Buffer (one serialize)
client.decryptFromBuffer(buf)FlashClientEncrypted Buffer โ†’ plain doc (partial field read)
FlashRecordCodecexportLow-level encode/decode helpers
FlashBinary.decodeRecord(buf)exportEngine buffer โ†’ object (for SQL/Wire/etc.)
FlashBinary.decodeRecords(bufs)exportBatch decode

Behavior changes (low-level) โ€‹

If you use FlashCollection directly (not FlashClient.collection()):

MethodBeforeNow
find()object[]Buffer[]
findOne()object | nullBuffer | null
insertOne()object onlyobject | Buffer
insertMany()object[] only(object | Buffer)[]

Use FlashBinary.decodeRecord() when you need plain objects from engine buffers.

Remote / FlashServer wire format โ€‹

Records over HTTP are sent as:

json
{ "_flashRecord": "<base64 FlashBinary buffer>" }

The remote client decodes automatically. No app changes if you use FlashClient with uri.

insertMany over remote uses POST /api/v1/insertMany/:collection (single round-trip batch).

Performance (v1.3.2) โ€‹

FeatureAPI
Turbo profileengineOptions: { performanceProfile: 'turbo' }
In-memory engineinMemory: true or storagePath: ':memory:'
Lazy field decrypt.select('field1 field2')
Partial buffer decryptFlashRecordCodec.decryptFields() / decryptFieldsFromBuffer()
Skip Merkle (turbo)disableMerkle: true (turbo default)

See Foundations ยง15.

Compact storage (storageProfile: 'compact') โ€‹

Minimal on-disk footprint โ€” use for bulk archives and non-searchable payloads:

javascript
const client = new FlashClient({
  secretKey: "key",
  storageProfile: "compact",
  fieldPolicy: {
    title: "exact", // equality search only
    body: "encrypted", // encrypt only โ€” smallest
    tags: "plaintext", // compressible metadata
  },
  engineOptions: { compressionLevel: 6 },
});
PolicyBlind indexTypical size vs searchable
encrypted / zk-secretnone~5โ€“15ร— smaller (strings)
exactexact trapdoor only~3โ€“8ร— smaller
searchableexact + ngrams + rangebaseline
plaintextnonesmallest + SSTable compresses

Plugin hooks โ€‹

beforeUpdate and afterUpdate are fully supported:

javascript
client.use({
  name: "audit",
  beforeUpdate(doc, col, previous) {
    doc.lastEditedBy = "system";
    return doc;
  },
  afterUpdate(doc, col) {
    console.log("updated", doc._id);
  },
});

TypeScript โ€‹

  • FlashQueryWhereBuilder<T> โ€” fixes fluent .where().gt() typing
  • FlashRecordCodec, encryptToBuffer, decryptFromBuffer
  • FlashCollection buffer return types
  • FlashPlugin.afterUpdate
  • FlashDatabase constructor accepts engineOptions

See Buffer Pipeline and TypeScript Support.


v1.3.1 โ€” Engine Fixes + Foundations โ€‹

Bug fixes โ€‹

IssueFix
TTL only scanned memtableTTL sweeps memtable + SSTables
getMerkleProof() async bugSync returns null if dirty; use getMerkleProofAsync()
count() loaded all docsUses engine count() when no filter
Missing beforeUpdate hookAdded on updateOne
Schema expireAfterSecondsAlso registers lifecycle()

New client foundations โ€‹

APIUse case
client.eventLog(name)Append-only time-ordered stream
client.counter(name)Atomic counters
client.queue(name)FIFO jobs with ack/fail
client.health()Engine capacity report
client.snapshot().flashpack export/import
autoTimestamps: true (default)Auto createdAt / updatedAt

See Universal Foundations.


v1.3.0 โ€” Universal Foundations (Cross-Domain) โ€‹

Introduced generic primitives instead of domain-named modules:

  • lifecycle(), paginate(), maintenance(), pipeline()
  • events(), use() plugins, tenant()
  • Positioning as zero-knowledge encrypted intelligence DB

See Positioning & Identity.


Migration checklist โ€‹

From โ‰ค1.3.0 โ†’ 1.3.2 โ€‹

  1. No breaking changes if you only use FlashClient.collection() CRUD.
  2. Engine-level code (FlashDatabase.collection().find()): decode buffers with FlashBinary.decodeRecord().
  3. Custom server clients: expect _flashRecord base64 over REST if reading raw responses.
  4. Enable timestamps: default on โ€” pass autoTimestamps: false to disable.
  5. Run tests after upgrade; 146 tests cover buffer + remote + foundations paths.
javascript
import { FlashClient } from "@moaaz-i/flash-db";

const client = new FlashClient({
  secretKey: process.env.FLASH_SECRET_KEY,
  storagePath: "./data",
  engineOptions: { durability: "balanced" },
  autoTimestamps: true,
});

// Foundations
client.maintenance({ autoStart: true });
const log = client.eventLog("events");
const jobs = client.queue("tasks");

Released under the Apache 2.0 License.