Skip to content

Commit 0064682

Browse files
committed
docs: update README with dialect/FTS/blob/exporter APIs, fix logo, bump v0.6.0
- Fix broken logo URL (manicinc → framersai) - Add SQL Dialect & Feature Abstractions section with examples - Document SqlDialect, IFullTextSearch, IBlobCodec, IDatabaseExporter - Update ARCHITECTURE.md with feature abstractions layer diagram - Bump version to 0.6.0, update CHANGELOG - Fix release workflow: remove --coverage flag that blocked npm publish
1 parent c3162dc commit 0064682

5 files changed

Lines changed: 171 additions & 5 deletions

File tree

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ jobs:
3232
- name: Install dependencies
3333
run: npm install
3434

35-
- name: Run tests with coverage
36-
run: npx vitest run --coverage
35+
- name: Run tests
36+
run: npx vitest run
3737
continue-on-error: false
3838

3939
- name: Build package

ARCHITECTURE.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,64 @@ const db = await getDB(user.id);
620620
await db.run('INSERT INTO posts (user_id, content) VALUES (?, ?)', [user.id, content]);
621621
```
622622

623+
## Feature Abstractions Layer
624+
625+
The `StorageFeatures` bundle provides platform-aware implementations of database features that differ between SQLite and PostgreSQL.
626+
627+
### Architecture
628+
629+
```
630+
┌─────────────────────────────────────────────┐
631+
│ Application Code │
632+
│ (uses dialect, fts, blobCodec, exporter) │
633+
├─────────────────────────────────────────────┤
634+
│ createStorageFeatures() │
635+
│ Inspects adapter.kind + runtime env │
636+
├──────────────────┬──────────────────────────┤
637+
│ SQLite Path │ PostgreSQL Path │
638+
│ SqliteDialect │ PostgresDialect │
639+
│ SqliteFts5 │ PostgresFts │
640+
│ NodeBlobCodec │ NodeBlobCodec │
641+
│ SqliteExporter │ PostgresExporter │
642+
├──────────────────┴──────────────────────────┤
643+
│ StorageAdapter │
644+
│ (run, get, all, exec, transaction, close) │
645+
└─────────────────────────────────────────────┘
646+
```
647+
648+
### Contracts
649+
650+
| Interface | Purpose | Implementations |
651+
|-----------|---------|----------------|
652+
| `SqlDialect` | SQL syntax differences (INSERT OR IGNORE vs ON CONFLICT, json_extract vs jsonb, etc.) | `SqliteDialect`, `PostgresDialect` |
653+
| `IFullTextSearch` | Full-text search DDL and query generation | `SqliteFts5` (FTS5), `PostgresFts` (tsvector/GIN) |
654+
| `IBlobCodec` | Binary vector encoding/decoding + SHA-256 | `NodeBlobCodec` (Buffer), `BrowserBlobCodec` (DataView) |
655+
| `IDatabaseExporter` | Database backup/export | `SqliteFileExporter` (VACUUM INTO), `PostgresExporter` (pg_dump) |
656+
657+
### File Layout
658+
659+
```
660+
src/
661+
core/contracts/
662+
dialect.ts # SqlDialect interface
663+
fts.ts # IFullTextSearch interface
664+
blobCodec.ts # IBlobCodec interface
665+
exporter.ts # IDatabaseExporter interface
666+
features.ts # StorageFeatures type + createStorageFeatures factory
667+
dialects/
668+
SqliteDialect.ts
669+
PostgresDialect.ts
670+
fts/
671+
SqliteFts5.ts
672+
PostgresFts.ts
673+
codecs/
674+
NodeBlobCodec.ts
675+
BrowserBlobCodec.ts
676+
exporters/
677+
SqliteFileExporter.ts
678+
PostgresExporter.ts
679+
```
680+
623681
---
624682

625683
For more examples and patterns, see the [GitHub repository](https://github.com/framersai/sql-storage-adapter).

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## [0.6.0] - 2026-03-27
2+
3+
### Added
4+
- **SqlDialect interface** with `SqliteDialect` and `PostgresDialect` implementations for cross-platform SQL generation (`insertOrIgnore`, `insertOrReplace`, `jsonExtract`, `ifnull`, `autoIncrementPrimaryKey`, `pragma`, `placeholder`)
5+
- **IFullTextSearch interface** with `SqliteFts5` (FTS5 virtual tables) and `PostgresFts` (tsvector/GIN) implementations for cross-platform full-text search (`createIndex`, `matchClause`, `rankExpression`, `rebuildCommand`, `syncInsert`, `sanitizeQuery`, `joinClause`)
6+
- **IBlobCodec interface** with `NodeBlobCodec` (Buffer) and `BrowserBlobCodec` (DataView/Uint8Array) implementations for cross-platform binary vector encoding
7+
- **IDatabaseExporter interface** with `SqliteFileExporter` (VACUUM INTO) and `PostgresExporter` (pg_dump) implementations
8+
- **`createStorageFeatures(adapter)`** factory function that returns the correct `StorageFeatures` bundle based on adapter kind and runtime environment
9+
- **Postgres dialect integration test** (skipped without `DATABASE_URL`)
10+
111
## [0.5.2] - 2026-02-06
212

313
### Added

README.md

Lines changed: 100 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<p align="center">
66
<a href="https://frame.dev" target="_blank" rel="noopener">
7-
<img src="https://raw.githubusercontent.com/manicinc/voice-chat-assistant/master/logos/frame-square-black-1024x1024-transparent.png" alt="Frame.dev" width="120">
7+
<img src="https://raw.githubusercontent.com/framersai/sql-storage-adapter/master/logos/frame-square-black-1024x1024-transparent.png" alt="Frame.dev" width="120">
88
</a>
99
<br>
1010
</p>
@@ -19,7 +19,7 @@
1919
2020
The SQL Storage Adapter provides a single, ergonomic interface over SQLite (native and WASM), PostgreSQL, Capacitor, IndexedDB, and in-memory stores. It handles adapter discovery, capability detection, and advanced features like cloud backups so you can focus on your application logic.
2121

22-
**🆕 NEW in v0.5.1:** Electron adapter with IPC bridge + Cross-platform real-time sync!
22+
**🆕 NEW in v0.6.0:** SQL Dialect abstractions for SQLite/Postgres parity + Cross-platform BLOB codec + Full-text search interface!
2323

2424
---
2525

@@ -31,6 +31,7 @@ The SQL Storage Adapter provides a single, ergonomic interface over SQLite (nati
3131
- [Cross-Platform Sync](#cross-platform-sync)
3232
- [Configuration & Resolution](#configuration--resolution)
3333
- [Platform Strategy](#platform-strategy)
34+
- [SQL Dialect & Feature Abstractions](#sql-dialect--feature-abstractions)
3435
- [CI, Releases, and Badges](#ci-releases-and-badges)
3536
- [Contributing](#contributing)
3637
- [License](#license)
@@ -48,6 +49,10 @@ The SQL Storage Adapter provides a single, ergonomic interface over SQLite (nati
4849
- **Portable packaging** – optional native dependencies; falls back to pure TypeScript/WASM adapters when native modules are unavailable.
4950
- **Browser-friendly** – Dynamic imports prevent bundlers from including server-only dependencies (`pg`, `path`) in browser builds.
5051
- **Mobile/Offline Parity** – Same APIs work across desktop, mobile (Capacitor), and browser with automatic sync support.
52+
- **🆕 SQL Dialect** – Write cross-platform SQL with `SqlDialect` interface. Automatically translates `INSERT OR IGNORE`, `json_extract`, `ifnull`, `PRAGMA` between SQLite and PostgreSQL.
53+
- **🆕 Full-Text Search**`IFullTextSearch` interface abstracts FTS5 (SQLite) and tsvector/GIN (PostgreSQL) with unified `createIndex`, `matchClause`, `rankExpression`, and `rebuildCommand` APIs.
54+
- **🆕 BLOB Codec**`IBlobCodec` for cross-platform binary vector storage. `NodeBlobCodec` (Buffer) for server, `BrowserBlobCodec` (DataView) for web.
55+
- **🆕 Database Export**`IDatabaseExporter` with `SqliteFileExporter` (VACUUM INTO) and `PostgresExporter` (pg_dump).
5156
- **CI-first design** – Vitest coverage, Codecov integration, and GitHub Actions workflows for linting, testing, releasing, and npm publish/tag automation.
5257

5358
## Installation
@@ -398,6 +403,99 @@ const db = await createDatabase({
398403

399404
See [**guides/OPTIMIZATION_GUIDE.md**](./guides/OPTIMIZATION_GUIDE.md) for complete configuration options.
400405

406+
## SQL Dialect & Feature Abstractions
407+
408+
Write cross-platform SQL that works on both SQLite and PostgreSQL without changing your application code.
409+
410+
### StorageFeatures Factory
411+
412+
```typescript
413+
import { resolveStorageAdapter, createStorageFeatures } from '@framers/sql-storage-adapter';
414+
415+
const adapter = await resolveStorageAdapter({ filePath: './app.db' });
416+
const features = createStorageFeatures(adapter);
417+
// features.dialect → SqliteDialect or PostgresDialect
418+
// features.fts → SqliteFts5 or PostgresFts
419+
// features.blobCodec → NodeBlobCodec or BrowserBlobCodec
420+
// features.exporter → SqliteFileExporter or PostgresExporter
421+
```
422+
423+
### SqlDialect — Cross-Platform SQL
424+
425+
```typescript
426+
const { dialect } = features;
427+
428+
// INSERT OR IGNORE (SQLite) → ON CONFLICT DO NOTHING (Postgres)
429+
const sql = dialect.insertOrIgnore('users', ['id', 'name'], ['?', '?']);
430+
431+
// INSERT OR REPLACE (SQLite) → ON CONFLICT DO UPDATE (Postgres)
432+
const upsert = dialect.insertOrReplace('users', ['id', 'name'], ['?', '?'], 'id');
433+
434+
// json_extract(col, '$.key') (SQLite) → (col::jsonb)->>'key' (Postgres)
435+
const expr = dialect.jsonExtract('metadata', '$.theme');
436+
437+
// ifnull(expr, fallback) (SQLite) → COALESCE(expr, fallback) (Postgres)
438+
const safe = dialect.ifnull(dialect.jsonExtract('config', '$.lang'), "'en'");
439+
440+
// PRAGMA (SQLite) → null/no-op (Postgres)
441+
const pragma = dialect.pragma('journal_mode', 'WAL');
442+
if (pragma) await adapter.exec(pragma);
443+
```
444+
445+
### IFullTextSearch — FTS5 & tsvector
446+
447+
```typescript
448+
const { fts } = features;
449+
450+
// Create index: FTS5 virtual table (SQLite) or tsvector + GIN (Postgres)
451+
await adapter.exec(fts.createIndex({
452+
table: 'docs_fts',
453+
columns: ['title', 'body'],
454+
contentTable: 'documents',
455+
tokenizer: 'porter ascii',
456+
}));
457+
458+
// Search query
459+
const sql = `
460+
SELECT t.*
461+
FROM ${fts.joinClause('documents', 't', 'fts', 'docs_fts')}
462+
WHERE ${fts.matchClause('docs_fts', '?')}
463+
ORDER BY ${fts.rankExpression('fts')}
464+
`;
465+
466+
// Rebuild index
467+
await adapter.exec(fts.rebuildCommand('docs_fts'));
468+
```
469+
470+
### IBlobCodec — Cross-Platform Binary Encoding
471+
472+
```typescript
473+
const { blobCodec } = features;
474+
475+
// Encode a float vector for storage
476+
const blob = blobCodec.encode([0.1, 0.2, -0.5, 1.0]);
477+
await adapter.run('INSERT INTO embeddings (vec) VALUES (?)', [blob]);
478+
479+
// Decode a stored vector
480+
const row = await adapter.get<{ vec: Uint8Array }>('SELECT vec FROM embeddings WHERE id = ?', [id]);
481+
const vector = blobCodec.decode(row!.vec);
482+
483+
// Cross-platform SHA-256
484+
const hash = await blobCodec.sha256('content to hash');
485+
```
486+
487+
### IDatabaseExporter — Portable Backups
488+
489+
```typescript
490+
const { exporter } = features;
491+
492+
// Export to file (VACUUM INTO on SQLite, pg_dump on Postgres)
493+
await exporter.exportToFile('/backups/snapshot.db');
494+
495+
// Export to bytes (for browser download or cloud upload)
496+
const bytes = await exporter.exportToBytes();
497+
```
498+
401499
## CI, Releases, and Badges
402500

403501
- GitHub Actions workflows:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@framers/sql-storage-adapter",
3-
"version": "0.5.3",
3+
"version": "0.6.0",
44
"description": "Robust cross-platform SQL storage abstraction with automatic fallbacks and runtime detection",
55
"type": "module",
66
"main": "dist/index.js",

0 commit comments

Comments
 (0)