tinbase 0.6.1 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -9
- package/dist/admin/ui.d.ts +1 -1
- package/dist/admin/ui.js +2 -2
- package/dist/cli.js +10 -5
- package/dist/cli.js.map +1 -1
- package/dist/cron/service.d.ts +6 -2
- package/dist/cron/service.js +5 -2
- package/dist/cron/service.js.map +1 -1
- package/dist/db/bootstrap.d.ts +1 -1
- package/dist/db/bootstrap.js +15 -2
- package/dist/db/bootstrap.js.map +1 -1
- package/dist/db/database.js +25 -6
- package/dist/db/database.js.map +1 -1
- package/dist/db/emulated.d.ts +4 -1
- package/dist/db/emulated.js +179 -0
- package/dist/db/emulated.js.map +1 -1
- package/dist/db/sql-compat.d.ts +32 -0
- package/dist/db/sql-compat.js +136 -0
- package/dist/db/sql-compat.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/net/service.d.ts +33 -0
- package/dist/net/service.js +98 -0
- package/dist/net/service.js.map +1 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -15,8 +15,9 @@ npx tinbase start
|
|
|
15
15
|
|
|
16
16
|
- **No Docker, no external services.** One runtime dependency: `@electric-sql/pglite`.
|
|
17
17
|
- **Real Postgres semantics.** RLS policies, `auth.uid()`, triggers, FKs - it is Postgres.
|
|
18
|
-
- **Three engines, one API.** Default is
|
|
18
|
+
- **Three engines, one API.** Default is embedded native Postgres 17 (macOS/Linux): ~59 MB of RAM at boot, PocketBase-class footprint, zero semantic differences; the first run downloads ~12 MB of binaries. `--engine wasm` runs PGlite (Postgres compiled to WASM) instead - portable, browser-ready, and the default on Windows. `--engine pgmem` is an ultralight pure-JS in-memory subset for local dev / previews - see [Engines](#engines).
|
|
19
19
|
- **Supabase CLI migration conventions.** Reads `supabase/migrations/*.sql` and `supabase/seed.sql`; tracks them in `supabase_migrations.schema_migrations`. Your migration files stay portable to hosted Supabase.
|
|
20
|
+
- **Runs real projects unchanged.** A project's `CREATE EXTENSION` statements for extensions tinbase can't install (pg_cron, pg_net, http, hypopg, …) are skipped rather than aborting; `CREATE INDEX CONCURRENTLY` is applied without the (transaction-illegal) `CONCURRENTLY`; each migration runs with a fresh `search_path` like the Supabase CLI; and Vault, pgmq, cron, pg_net, and `moddatetime` are emulated. As a test, [Cap-go/capgo](https://github.com/Cap-go/capgo)'s **335 migrations + seed apply and query cleanly**.
|
|
20
21
|
- **Browser-ready core.** Every service is a pure `(Request) => Response` fetch handler. In Node it's served over HTTP; in the browser you can hand it to supabase-js as a custom `fetch` and run the whole backend in-process (PGlite already runs in the browser via IndexedDB/OPFS).
|
|
21
22
|
|
|
22
23
|
## Quick start
|
|
@@ -63,13 +64,13 @@ tinbase db diff # DDL for schema changes not yet in migrations (-f <name> to
|
|
|
63
64
|
--data-dir <path> PGlite data dir (default <dir>/.tinbase/db)
|
|
64
65
|
--jwt-secret <s> JWT secret (or TINBASE_JWT_SECRET)
|
|
65
66
|
--memory in-memory database, no persistence (wasm engine)
|
|
66
|
-
--engine <e>
|
|
67
|
+
--engine <e> native (default), wasm, or pgmem
|
|
67
68
|
```
|
|
68
69
|
|
|
69
70
|
### Engines
|
|
70
71
|
|
|
71
|
-
- **
|
|
72
|
-
- **
|
|
72
|
+
- **native** (default on macOS/Linux): embedded native Postgres 17. First run downloads platform binaries (~12 MB, from [theseus-rs/postgresql-binaries](https://github.com/theseus-rs/postgresql-binaries), cached in `~/.cache/tinbase`), then `initdb` with memory-lean settings. ~59 MB RAM at boot. Listens only on a private unix socket (0700 dir, trust auth) - never TCP. macOS/Linux on x64/arm64.
|
|
73
|
+
- **wasm** (default on Windows): PGlite. Zero setup, runs anywhere Node runs - and in the browser. Its WASM heap sits around ~575-650 MB and does not shrink under load.
|
|
73
74
|
|
|
74
75
|
- **pgmem** (`--engine pgmem`): an ultralight, pure-JS, in-memory subset via [pg-mem](https://github.com/oguimbal/pg-mem) — **~3.6 MB install, no WASM**, so it's the lightest option for the browser (RapidNative local-dev / previews). Runs the REST CRUD surface, email/password auth, **edge functions, realtime (broadcast/presence + `postgres_changes`), and database webhooks**. pg-mem has no triggers or LISTEN/NOTIFY, so realtime/webhook change events are synthesized in JS by the REST layer (every write goes through it in-process). What's *not* here: **RLS** (so realtime/webhook events are delivered unfiltered, not per-subscriber), **cron**, and **pgmq** - RLS DDL in migrations is skipped, not fatal. Local-dev / preview only — never production.
|
|
75
76
|
|
|
@@ -78,7 +79,7 @@ The wasm and native engines run the identical bootstrap, migrations, RLS, and re
|
|
|
78
79
|
### Single-binary build
|
|
79
80
|
|
|
80
81
|
```bash
|
|
81
|
-
npm run build:binary # requires bun; emits dist-bin/tinbase (~
|
|
82
|
+
npm run build:binary # requires bun; emits dist-bin/tinbase (~58 MB)
|
|
82
83
|
|
|
83
84
|
./tinbase start # that's the whole deployment
|
|
84
85
|
```
|
|
@@ -120,7 +121,8 @@ const server = await serve(backend, { port: 54321 })
|
|
|
120
121
|
| Storage | `/storage/v1` | bucket CRUD, upload (raw + multipart), download, public objects, signed URLs, signed upload URLs, list with folder entries, move/copy, remove, size/MIME limits. Metadata lives in `storage.objects` with RLS enforced; bytes go through a pluggable driver (fs in Node, memory anywhere) |
|
|
121
122
|
| Edge Functions | `/functions/v1` | `supabase.functions.invoke()` - Supabase-style `Deno.serve(handler)` functions (with `Deno.env`) run unchanged, as do `export default` handlers; loaded from `supabase/functions/<name>/index.{ts,js,mjs}` by the CLI or passed via `createBackend({ functions })`. Web-API functions work as-is; `npm:`/`jsr:`/URL imports still need bundling |
|
|
122
123
|
| Queues (pgmq) | `pgmq.*` | Message queues via a pure-SQL pgmq subset (create/send/read/pop/delete/archive, visibility timeouts). Call from SQL or `supabase.schema('pgmq').rpc(...)`. No extension |
|
|
123
|
-
| Cron | `cron.*` | Scheduled jobs
|
|
124
|
+
| Cron | `cron.*` | Scheduled jobs, drop-in with pg_cron's API — `cron.schedule(name, '*/5 * * * *', 'sql')` (also the `'N seconds'` form), `cron.unschedule(...)`, and the `cron.job` / `cron.job_run_details` tables. Schedules match in **UTC**, like hosted pg_cron; an in-process scheduler runs due jobs and logs to `cron.job_run_details`. Jobs run while tinbase is up, with service-role privileges. No extension |
|
|
125
|
+
| HTTP from SQL (pg_net) | `net.*` | `net.http_post` / `net.http_get` / `net.http_delete(...)` enqueue a request that an in-process worker sends, recording the reply in `net._http_response`. Lets a cron job or trigger call an Edge Function or any URL — the common Supabase `cron.schedule(..., $$ select net.http_post(...) $$)` pattern works unchanged. No extension |
|
|
124
126
|
| Database Webhooks | config | Fire HTTP requests on table INSERT/UPDATE/DELETE with Supabase's exact payload (`type`/`table`/`schema`/`record`/`old_record`). Configured via `createBackend({ webhooks })`, `backend.webhooks.register()`, or `supabase/webhooks.json`. Built on the CDC pipeline — no extension needed |
|
|
125
127
|
| Studio (Admin UI) | `/_/` | A Supabase-Studio-style dashboard (React + Radix + Tailwind): Table Editor with full row CRUD, SQL editor, user management, bucket/object CRUD, and a database overview. One self-contained HTML file (works in the single binary); log in with the service_role key |
|
|
126
128
|
| Realtime | `/realtime/v1` | Phoenix protocol (v1 JSON and v2 array/binary serializers), `postgres_changes` (INSERT/UPDATE/DELETE, filters) fed by triggers + `pg_notify`, broadcast (incl. binary payloads), presence. WebSocket server is a ~150-line RFC 6455 implementation - no `ws` dependency |
|
|
@@ -180,7 +182,7 @@ Measured on an Apple Silicon Mac (48 GB), macOS 15. Same workload for all three:
|
|
|
180
182
|
| Runtime memory at boot | 49 MB | 59 MB | 71 MB | ~610 MB² | 15 MB | 1,441 MB |
|
|
181
183
|
| Runtime memory after workload | 66 MB | 100 MB | 185 MB | ~640 MB² | 24 MB | 1,626 MB |
|
|
182
184
|
| Data on disk (1k rows) | 39 MB | 39 MB | 0 (in-memory) | 40 MB | 7 MB | 70 MB |
|
|
183
|
-
| Install size | 92 MB (
|
|
185
|
+
| Install size | 92 MB (58 MB binary + PG) | 36 MB³ | 3.6 MB³ | 27 MB³ | 30 MB | 2,291 MB⁴ |
|
|
184
186
|
| Processes | 2 | 2 | 1 | 1 | 1 | 12 containers + Docker |
|
|
185
187
|
| 1,000 inserts | 0.4 s | 0.5 s | 0.8 s | 0.8 s | 0.3 s | 1.1 s |
|
|
186
188
|
| 1,000 filtered reads | 0.3 s | 0.4 s | 0.8 s | 0.9 s | 0.3 s | 1.0 s |
|
|
@@ -223,7 +225,7 @@ Beyond the client SDK, the local platform features real projects depend on also
|
|
|
223
225
|
|
|
224
226
|
## Tests
|
|
225
227
|
|
|
226
|
-
|
|
228
|
+
The integration suite drives the real `@supabase/supabase-js` against the backend (REST via in-process fetch, realtime over actual WebSockets); the full suite — **168 tests** — passes on both the wasm and native engines:
|
|
227
229
|
|
|
228
230
|
```bash
|
|
229
231
|
npm test
|
|
@@ -237,5 +239,5 @@ tinbase aims to be a local, Docker-free replacement for `supabase start` where *
|
|
|
237
239
|
|
|
238
240
|
tinbase was built for [lifo](https://lifo.sh) - a project that maps Linux APIs into the browser - to let **Expo apps run fully in the browser with full-stack capability** (database, auth, storage, realtime, no server). It is part of [RapidNative](https://rapidnative.com). That origin drives the architecture:
|
|
239
241
|
|
|
240
|
-
1. Every service is a pure fetch handler and the
|
|
242
|
+
1. Every service is a pure fetch handler, and the `wasm` engine is Postgres compiled to WASM (PGlite), so with it the whole backend can run **in-process inside a browser tab**.
|
|
241
243
|
2. The same design makes a lighter Supabase for local dev and self-contained apps - `npx tinbase start` instead of Docker Compose.
|