DBDelve
DBDelve는 Rust 기반 빠른 다중 엔진 데이터베이스 클라이언트, 무료 오픈소스, 텔레메트리 없음
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
JavaScript and TypeScript SDK for WaveHouse (@wavehouse/sdk)
README 전체를 불러오는 중입니다.
README 전문 보기 ↗TypeScript client for WaveHouse — schema-aware real-time API gateway for ClickHouse. One runtime dependency (eventsource-parser, ~1.4 KB gzipped, itself dependency-free).
npm install @wavehouse/sdk
Requires Node 22 or newer — the only line this SDK is tested against; Node 18 and 20 are past upstream end-of-life. Neither browsers nor Node need a polyfill: streaming runs on fetch, like the rest of the SDK — see Runtime support.
This works in any framework that uses a bundler — React, Vue, Svelte, Angular, Astro, SolidJS, or plain Vite — with import { createClient } from '@wavehouse/sdk'. The SDK and the server share the SSE wire protocol, so move them as a pair — a skewed pair delivers no usable rows and raises no error (details).
The package is published with npm provenance — npm shows a verified provenance badge on the package page, and npm audit signatures checks the attestation against this repository's signed build.
No bundler, no npm, no framework required — drop the SDK straight into an HTML file you deploy over FTP, object storage, or any static host.
ES module (recommended). Modern browsers run type="module" natively:
<script type="module">
import { createClient } from 'https://esm.sh/@wavehouse/sdk';
const wh = createClient({ baseURL: 'https://your-wavehouse.example.com' });
const { data, error } = await wh.from('clicks').select('page').limit(10);
console.log(data ?? error);
</script>
Pin a version for production (https://esm.sh/@wavehouse/[email protected]). jsDelivr (https://cdn.jsdelivr.net/npm/@wavehouse/sdk/+esm) and unpkg (https://unpkg.com/@wavehouse/sdk?module) serve the same ES module. The SDK and the server share the SSE wire protocol, so pin them as a pair — a skewed pair delivers no usable rows and raises no error.
Classic global (<script src>). For pages that can't use ES modules, the bundled IIFE build attaches everything to a WaveHouse global:
<script src="https://cdn.jsdelivr.net/npm/@wavehouse/sdk"></script>
<script>
const wh = WaveHouse.createClient({ baseURL: 'https://your-wavehouse.example.com' });
wh.from('clicks').select('page').limit(10).then(({ data }) => console.log(data));
</script>
Versioning. A bare CDN URL serves the latest published release; pin for production (@wavehouse/[email protected]) or float on a range (@0 for the newest 0.x, @0.2 for 0.2.x). Builds from main are published under the dev tag — @wavehouse/sdk@dev — for trying unreleased changes. Whichever you choose, move the SDK and the server together: they share the SSE wire protocol, and a skewed pair delivers no usable rows and raises no error — a newer SDK drops every row, an older one hands you an event per frame with data: undefined.
Streaming (.stream()) runs on fetch, so it works in both forms with no polyfill.
import { createClient } from '@wavehouse/sdk';
const wh = createClient({
baseURL: 'http://localhost:8080',
auth: async () => getAccessToken(), // omit for public access
});
baseURL may include a path prefix (https://app.example.com/api/wavehouse) when WaveHouse is served under one — see Serving under a path prefix.
// Structured query with the builder
const { data, error } = await wh
.from('clicks')
.select('page', 'button')
.where('score', '>', 10)
.count('*', 'total')
.groupBy('page', 'button')
.orderBy('total', 'desc')
.limit(50)
.timeRange('received_timestamp', '1h');
// Raw SQL (requires admin role)
const { data } = await wh.sql('SELECT page, count() FROM clicks GROUP BY page LIMIT 10');
// Named pipe
const { data } = await wh.pipe('top_pages', { start_date: '2026-01-01', limit: 50 });
const { error } = await wh.from('clicks').insert({ page: '/home', button: 'signup', score: 42.5 });
// Callback pattern
const stream = wh.from('clicks').stream();
const unsub = stream.subscribe({
next: (event) => console.log(event.data),
status: (state) => console.log(state), // 'connecting' | 'live' | 'reconnecting' | 'closed'
});
// Async iterator pattern
for await (const event of wh.from('clicks').stream()) {
console.log(event.table, event.data);
}
let result = await wh.from('clicks').select().orderBy('received_timestamp', 'desc').limit(100);
while (result.hasMore && result.next) {
result = await result.next();
}
Pass a Database type for autocomplete on table names and row shapes:
interface Database {
clicks: { page: string; button: string; score: number; received_timestamp: string };
users: { id: string; name: string; email: string };
}
const wh = createClient<Database>({ baseURL: '...' });
const { data } = await wh.from('clicks').select('page').limit(10);
// data: Array<{ page: string; button: string; ... }> | null
Async request methods return a Result<T> object — destructure it as { data, error } — and never throw for anything the server returns. .stream() and .liveQuery() return controllers instead, reporting failures through the subscriber's error callback.
여기까지가 README 앞부분입니다. 나머지는 원문에서 읽을 수 있습니다. README 전문 보기 ↗