|
| 1 | +// Landing-page FAQ — a custom accordion instead of oxidoc's <Accordion> |
| 2 | +// (whose <details> + grid-row animation is hard to retheme cleanly on the |
| 3 | +// dark page). Content lives here, pre-written, since custom components can't |
| 4 | +// carry RDX children. Rendered by <Faq />. RDX emits a bare lowercased |
| 5 | +// <faq>, so we upgrade by query selector. |
| 6 | + |
| 7 | +(function () { |
| 8 | + var ITEMS = [ |
| 9 | + { |
| 10 | + q: "Isn't one binary with 8 engines just a monolith?", |
| 11 | + a: "Yes — deliberately. Sharing one process means cross-engine queries run in the same address space with zero network hops. The alternative (5 services) is a distributed monolith pretending not to be one, with worse latency and worse consistency. We scale horizontally with auto-rebalancing vShards, not by splitting engines.", |
| 12 | + }, |
| 13 | + { |
| 14 | + q: "Why not just Postgres + pgvector + extensions?", |
| 15 | + a: "Postgres is our wire protocol — that's why your existing client works unchanged. But pgvector bolts a vector index onto a row-store planner that doesn't understand hybrid ranking. We built the planner from scratch to route each sub-query to the engine that fits: graph traversals use CSR, vector search uses HNSW, analytics use columnar.", |
| 16 | + }, |
| 17 | + { |
| 18 | + q: "What about multi-tenancy, RLS, and audit logs?", |
| 19 | + a: "All first-class. Row-Level Security via <code>CREATE RLS POLICY</code> with <code>$auth.id</code> / <code>$auth.role</code> context — applied transparently to every engine, no app changes. Audit logging captures who did what and when, tamper-evident. Tenant isolation, RBAC, and RLS compose so you can run real multi-tenant SaaS on one cluster without writing your own row filters.", |
| 20 | + }, |
| 21 | + { |
| 22 | + q: "Can I query the database as of a past point in time?", |
| 23 | + a: "Yes — for the engines where it matters. Bitemporal covers graph, strict documents, columnar (plain + timeseries), arrays, and CRDT sync. Every write there records both <em>valid time</em> (when the fact was true in the real world) and <em>system time</em> (when the database learned it). Run any query <code>AS OF</code> a past moment, audit a row's full history, or do GDPR-compliant erasure that preserves the audit trail. Vector, FTS, KV, and spatial indexes stay current-state-only by design — that's where you want speed, not history.", |
| 24 | + }, |
| 25 | + { |
| 26 | + q: "Do you actually handle scientific array data, or is that marketing?", |
| 27 | + a: "Real engine. ND coordinate-indexed sparse arrays with Hilbert/Z-order locality, per-tile MBR pruning, compression via our codec stack, WAL-durable, Raft-replicated. Built to replace TileDB / SciDB / Zarr for genomics (variant × sample × position), earth observation (lat × lon × band × time), and climate cubes. And yes — you can join an array slice against a vector ANN search in one SQL query.", |
| 28 | + }, |
| 29 | + { |
| 30 | + q: "Does it run on mobile / offline / in the browser?", |
| 31 | + a: "Yes. NodeDB-Lite is a 4.5MB WASM + iOS/Android FFI build — the same 8 engines, embedded. Edge-to-cloud sync is CRDT-native via Loro, so offline writes merge deterministically when the device reconnects.", |
| 32 | + }, |
| 33 | + ]; |
| 34 | + |
| 35 | + function build(host) { |
| 36 | + var openFirst = host.getAttribute("open-first") !== "false"; |
| 37 | + var html = '<div class="ndb-faq-list">'; |
| 38 | + ITEMS.forEach(function (it, i) { |
| 39 | + var open = i === 0 && openFirst; |
| 40 | + html += |
| 41 | + '<div class="ndb-faq-item' + (open ? " is-open" : "") + '">' + |
| 42 | + '<button class="ndb-faq-q" type="button" aria-expanded="' + (open ? "true" : "false") + '">' + |
| 43 | + "<span>" + it.q + "</span>" + |
| 44 | + '<span class="ndb-faq-icon" aria-hidden="true">+</span>' + |
| 45 | + "</button>" + |
| 46 | + '<div class="ndb-faq-panel"><div class="ndb-faq-a">' + it.a + "</div></div>" + |
| 47 | + "</div>"; |
| 48 | + }); |
| 49 | + html += "</div>"; |
| 50 | + host.innerHTML = html; |
| 51 | + |
| 52 | + host.querySelectorAll(".ndb-faq-q").forEach(function (btn) { |
| 53 | + btn.addEventListener("click", function () { |
| 54 | + var item = btn.parentElement; |
| 55 | + var nowOpen = item.classList.toggle("is-open"); |
| 56 | + btn.setAttribute("aria-expanded", nowOpen ? "true" : "false"); |
| 57 | + }); |
| 58 | + }); |
| 59 | + } |
| 60 | + |
| 61 | + function init() { |
| 62 | + document.querySelectorAll("faq, Faq").forEach(build); |
| 63 | + } |
| 64 | + |
| 65 | + if (document.readyState === "loading") { |
| 66 | + document.addEventListener("DOMContentLoaded", init); |
| 67 | + } else { |
| 68 | + init(); |
| 69 | + } |
| 70 | +})(); |
0 commit comments