@supabase/lite 0.8.1-next.2 → 0.9.1-next.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.
Files changed (39) hide show
  1. package/FEATURES.md +176 -0
  2. package/LIMITATIONS.md +1 -0
  3. package/README.md +1 -0
  4. package/STATUS.md +7 -1
  5. package/dist/cli/index.js +86 -86
  6. package/dist/db/postgres/pglite/PgliteConnection.js +17 -17
  7. package/dist/index.d.ts +26 -2
  8. package/dist/index.js +55 -55
  9. package/dist/vite/index.d.ts +26 -2
  10. package/docs/auth/email.mdx +214 -0
  11. package/docs/auth/not-supported.mdx +57 -0
  12. package/docs/auth/overview.mdx +52 -0
  13. package/docs/auth/supported-flows.mdx +120 -0
  14. package/docs/cli/overview.mdx +112 -0
  15. package/docs/cli/telemetry.mdx +34 -0
  16. package/docs/compatibility.mdx +115 -0
  17. package/docs/database/backends.mdx +118 -0
  18. package/docs/database/data-api.mdx +90 -0
  19. package/docs/database/functions-triggers.mdx +93 -0
  20. package/docs/database/migrations.mdx +93 -0
  21. package/docs/database/overview.mdx +66 -0
  22. package/docs/database/postgres-sqlite-translation.mdx +130 -0
  23. package/docs/database/rls.mdx +159 -0
  24. package/docs/database/schemas.mdx +58 -0
  25. package/docs/index.mdx +49 -0
  26. package/docs/integrations/embedded.mdx +83 -0
  27. package/docs/integrations/frameworks.mdx +83 -0
  28. package/docs/integrations/vite.mdx +85 -0
  29. package/docs/llms.txt +52 -0
  30. package/docs/other/edge-functions.mdx +34 -0
  31. package/docs/other/realtime.mdx +22 -0
  32. package/docs/quickstart.mdx +150 -0
  33. package/docs/running.mdx +117 -0
  34. package/docs/storage/adapters.mdx +75 -0
  35. package/docs/storage/limitations.mdx +30 -0
  36. package/docs/storage/overview.mdx +82 -0
  37. package/docs/upgrade.mdx +108 -0
  38. package/package.json +4 -1
  39. package/skills/supalite/SKILL.md +5 -3
package/FEATURES.md ADDED
@@ -0,0 +1,176 @@
1
+ # Feature Parity
2
+
3
+ Capability-level view of how @supabase/lite maps to Supabase. [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md) is the per-method API matrix; this document groups features into capabilities and, for anything not yet supported, adds two columns: an **Effort** estimate and the **Blocker** reason.
4
+
5
+ Compatibility is measured from the `@supabase/supabase-js` surface; direct Postgres wire-protocol access is not a target.
6
+
7
+ ## Legend
8
+
9
+ Status (same icons as [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md)):
10
+
11
+ | Icon | Meaning |
12
+ |------|---------|
13
+ | ✅ | Supported end-to-end |
14
+ | ⚠️ | Partial, works with caveats |
15
+ | 🔄 | Planned / not built yet |
16
+ | ❌ | Not feasible on this path |
17
+ | ⚫ | N/A (client-side only, or no backend needed) |
18
+
19
+ For rows that are not fully ✅, two columns estimate the cost of closing the gap.
20
+
21
+ **Effort** (T-shirt size, relative engineering cost):
22
+
23
+ | Size | Rough meaning |
24
+ |------|---------------|
25
+ | `S` | Small, self-contained change |
26
+ | `M` | A feature's worth of work |
27
+ | `L` | Large, multi-part or new subsystem |
28
+ | `XL` | Major subsystem or new runtime |
29
+
30
+ **Blocker** (why it isn't trivial):
31
+
32
+ | Blocker | Meaning |
33
+ |---------|---------|
34
+ | `platform-limited` | SQLite lacks the primitive (range types, stored procedures, logical replication); any emulation is partial/lossy |
35
+ | `extension-required` | Needs an extension not loadable across all targets (e.g. pgvector / sqlite-vec, full REGEXP) |
36
+ | `external-service` | Needs an outside dependency (SMTP, SMS provider, OAuth provider apps) |
37
+
38
+ `-` marks not-applicable: both columns on ✅ rows, and the Blocker column on planned features with no hard blocker (just ordinary backlog work).
39
+
40
+ > **The SQLite vs Postgres split matters.** @supabase/lite runs on SQLite backends (`node:sqlite`, `bun:sqlite`, WASM, Cloudflare D1/DO) and on Postgres backends (PGlite, PostgreSQL, Supabase Cloud). Many "not feasible on SQLite" features work natively on the Postgres path. The Data tables below carry both columns; Auth and Storage are backend services that behave the same across drivers. One exception: on the Cloudflare D1 backend, multi-statement Auth transaction spans (OAuth callback/token writes, email-change and other OTP verification) run best-effort without a wrapping transaction (D1 has no callback transaction API); single-statement guards still prevent auth-code/state reuse. All other backends, including Durable Objects, are fully transactional.
41
+
42
+ ---
43
+
44
+ ## Data API (PostgREST)
45
+
46
+ CRUD, filtering, embedding, and RLS over your tables. This is the most complete surface. Method-level detail and per-operator notes live in [STATUS.md → Database API](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#database-api-postgrest-compatible).
47
+
48
+ | Capability | SQLite | Postgres | Effort | Blocker | Notes |
49
+ |------------|:------:|:--------:|:------:|:-------:|-------|
50
+ | select / insert / update / delete / upsert | ✅ | ✅ | - | - | Batch ops, `ON CONFLICT`, `RETURNING` |
51
+ | Comparison filters (eq, neq, gt/gte/lt/lte, in, is, …) | ✅ | ✅ | - | - | 10/10 |
52
+ | Pattern matching (like, ilike, + quantified) | ✅ | ✅ | - | - | 6/6 |
53
+ | Ordering, limit, range/offset, single/maybeSingle | ✅ | ✅ | - | - | NULLS FIRST/LAST |
54
+ | Logical (or, and, not, match, filter) | ✅ | ✅ | - | - | |
55
+ | JSON path (`->`, `->>`) in select/order/where | ✅ | ✅ | - | - | |
56
+ | Resource embedding (FK joins, `!inner`, spreads, nested, aggregates) | ✅ | ✅ | - | - | |
57
+ | Embedding through views (view→base-table FK tracing) | ⚠️ | ⚠️ | `M` | `platform-limited` | Simple updatable views resolve embeds via their base-table FKs on both paths. Postgres path additionally supports: **materialized views** (introspected via `pg_matviews`/`relkind 'm'` and treated as routable relations with derived FKs) and **multi-level recursive view-of-view** (column maps composed transitively to the ultimate physical base via a fixpoint loop with a depth-16 cap and cycle guard). Not yet traced on either path: complex views (CTE, GROUP BY, subselect-in-FROM, JOINs), and same-name relation collisions across two exposed schemas. See [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#database-api-postgrest-compatible) / [LIMITATIONS.md](https://github.com/supabase-community/lite/blob/HEAD/LIMITATIONS.md). |
58
+ | Bulk ops & `Prefer` headers (representation, merge/ignore-duplicates, max-affected) | ✅ | ✅ | - | - | |
59
+ | RLS enforcement (`auth.uid()`/`role()`/`jwt()`, permissive/restrictive, per-command, roles) | ✅ | ✅ | - | - | App-layer rewrite on SQLite; native on Postgres. On `sqlite-postgres` the policy metadata persists to `supabase/.temp/.deparse-cache.json`, so `lite start` (which never migrates) restores it, recalculates it from the applied migration history when the cache is gone, and fails closed instead of booting with RLS off. See [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#row-level-security-rls). |
60
+ | CSV input/output (`csv()`) | ✅ | ✅ | - | - | Via `text/csv` Accept/Content-Type |
61
+ | Response utilities (`abortSignal`, `setHeader`, `throwOnError`, `maxAffected`) | ✅ | ✅ | - | - | |
62
+ | CORS / `OPTIONS` preflight | ✅ | ✅ | - | - | Server-wide on `/auth`, `/rest`, `/storage`; preflight answered before auth, origin `*`, exposes `Content-Range`. |
63
+ | PostgreSQL extension declarations | ⚠️ | ⚠️ | `XL` | `extension-required` | SQLite treats `plpgsql`, `pgcrypto`, and `uuid-ossp` declarations plus their declarative schema/drop reconciliation as compatibility no-ops; unsupported creates and mutations fail during translation. PGlite runs only its configured extensions; PostgreSQL delegates to the server. See [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#extension-statements). |
64
+ | Full-text search (fts/plfts/phfts/wfts) | ⚠️ | ✅ | `L` | `platform-limited` | SQLite uses a LIKE-based lexeme approximation, not FTS5 ranking or tsvector semantics. See [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#full-text-search). |
65
+ | Regex (`regexMatch`/`regexIMatch`) | ⚠️ | ✅ | `M` | `extension-required` | Only simple anchored/literal patterns today. Full regex needs a registered `REGEXP` function, available on `node:`/`bun:sqlite` but not WASM/D1. See [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#regex). |
66
+ | Array/JSON containment (`contains`, `containedBy`, `overlaps`) | ⚠️ | ✅ | `M` | `platform-limited` | Scalar arrays + shallow objects work via `json_each`/`json_extract`; arrays-of-objects and nested objects do not. See [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#array--json-filters). |
67
+ | Custom domain types / data representations | ⚠️ | ⚠️ | `M` | `platform-limited` | Postgres: domain columns with `CAST(… AS json)` render via that cast on reads/`RETURNING`, and JSON values mutated **into** a domain (epoch/base64/decimal) are converted; sessions run in UTC by default (configurable). SQLite: built-in shims for the known data-rep types. Remaining gap: domain formatting through cross-relation embeds. See [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#translated-field-types). |
68
+ | `explain()` | ⚠️ | ⚠️ | `M` | `-` | Returns compiled SQL, not a real query plan. |
69
+ | OpenAPI / schema spec at `/rest/v1/` | ⚠️ | ⚠️ | `M` | `-` | A mock spec is served; not generated from live schema. |
70
+ | `count=planned` / `count=estimated` | ⚠️ | ⚠️ | `S` | `-` | Parsed but treated as exact on SQLite. |
71
+ | Quantified comparisons (`eq(any)`, `gt(all)`, …) | 🔄 | ✅ | `M` | `-` | No SQLite array type, but emulatable by expanding to `OR`/`AND` chains over the literal list. |
72
+ | Embedded dotted-path filters (`.eq('rel.col', v)`) | 🔄 | ✅ | `M` | `-` | Not rewritten into the embedded subquery on SQLite. Workaround in [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#embedded-filters). |
73
+ | `rpc()` (stored procedures) | ❌ | ✅ | `XL` | `platform-limited` | Postgres RPC depends on `CREATE FUNCTION … LANGUAGE sql/plpgsql`. SQLite has no stored-procedure model, and the project deliberately avoids a parallel JS-function registry. Use an HTTP endpoint, or a Postgres driver. Supports PostgREST function response control: `response.status`/`response.headers` GUCs override the HTTP status/headers (invalid → PGRST112/PGRST111), GET/HEAD calls run in a read-only transaction (a mutating function raises 25006 → 405), and `request.method`/`path`/`headers` GUCs are injected for functions that read the HTTP context. A function returning a media-type **domain** (e.g. `returns "text/plain"`/`"image/png"`/`"*/*"`) and matched by the request `Accept` emits the raw scalar (text or bytes) with that `Content-Type` instead of JSON; the `response.headers` GUC can override the Content-Type. Gap: table custom-aggregate media handlers. |
74
+ | Computed columns & relationships (PostgREST) | ❌ | ✅ | `L` | `platform-limited` | Postgres: function-based computed columns `fn(row)→scalar` (select + filter, incl. FTS) and computed relationships `fn(row)→[SETOF] table` (embed with no FK, incl. FK/o2o override, self-joins, nested, and on `SETOF` RPC results). Resolved from introspected `pg_proc` metadata, schema-scoped. SQLite has no stored functions. Gap: computed columns on an RPC result (`*_on_rpc`). |
75
+ | Composite-type columns (`CREATE TYPE … AS (…)`) | ❌ | ✅ | `M` | `platform-limited` | Postgres: composite-field access in select/order/filter (`->`/`->>` → `(col).field`) and composite columns rendered as JSON objects (`to_jsonb`) on reads and `RETURNING`. SQLite has no composite types (spec fixtures store the column as JSON there). |
76
+ | Partitioned tables (declarative partitioning) | ❌ | ✅ | `M` | `platform-limited` | Postgres: the partitioned parent is queryable; individual partitions are hidden from the relation cache like PostgREST — direct access → 404, embedding a partition → no-relationship error with a "did you mean '<parent>'" hint. SQLite has no partitioning. |
77
+ | Range operators (`rangeGt`, `rangeAdjacent`, …) | ❌ | ✅ | `XL` | `platform-limited` | No range types in SQLite. |
78
+ | `schema()` (multi-schema) | ❌ | ✅ | `L` | `platform-limited` | SQLite is single-schema. |
79
+ | `geojson()` | ❌ | ❌ | `XL` | `extension-required` | Needs SpatiaLite (SQLite) or PostGIS (Postgres). |
80
+ | `rollback()` (Prefer tx-rollback) | ❌ | ❌ | `S` | `-` | PostgREST-specific; not implemented on either path. |
81
+ | Vector / semantic search (`pgvector`) | ❌ | ❌ | `XL` | `extension-required` | Hosted/CLI Supabase ships `pgvector`; lite does not. `sqlite-vec` is a loadable extension unavailable on WASM/D1, and the PGlite/`postgres` drivers here don't enable `pgvector`. Point users at hosted Supabase for embeddings. |
82
+
83
+ ---
84
+
85
+ ## Auth (GoTrue)
86
+
87
+ GoTrue-compatible endpoints at `/auth/v1/*`, backed by `app/src/auth/`. Email/password, OTP, sessions, RLS auth context, and OAuth sign-in (`github`/`google`) are solid; other OAuth providers, admin, and MFA are the main gaps. Method list in [STATUS.md → Auth API](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#auth-api-gotrue-compatible).
88
+
89
+ | Capability | Status | Effort | Blocker | Notes |
90
+ |------------|:------:|:------:|:-------:|-------|
91
+ | Email + password sign-up / sign-in | ✅ | - | - | bcrypt, optional metadata, confirmation flow |
92
+ | Magic link / email OTP (`signInWithOtp`, `verifyOtp`) | ✅ | - | - | signup, magiclink, recovery, email_change, reauthentication; numeric code + `token_hash` both verify against the DB (durable on Workers), `otp_expiry`/`otp_length` honored |
93
+ | JWT issuance, refresh-token rotation, sessions | ✅ | - | - | Revocation, reuse handling, timebox/inactivity expiry |
94
+ | Password recovery (`recover`, `resend`, `reauthenticate`) | ✅ | - | - | |
95
+ | `getUser` / `updateUser` (metadata, password, email change) | ✅ | - | - | Secure email change (`double_confirm_changes=true`) is ⚠️ partial: spec-compatible (confirms from the current mailbox before finalizing) but not GoTrue's full two-mailbox flow. See [LIMITATIONS.md](https://github.com/supabase-community/lite/blob/HEAD/LIMITATIONS.md#auth-shipped-with-caveats). |
96
+ | RLS auth context (`auth.uid()`, `auth.role()`, `auth.jwt()`) | ✅ | - | - | Shared with the Data API |
97
+ | API keys (`sb_publishable_*` → `anon`, `sb_secret_*` → `service_role`) | ✅ | - | - | Enforced on `/rest/v1` and `/auth/v1` when `auth.publishable_key`/`auth.secret_key` are configured; legacy JWT-as-apikey not supported. See [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#api-keys). |
98
+ | Local admin mode (keyless local requests run as `service_role`) | ✅ | - | - | On by default for `lite dev`/`lite start` (`/rest/v1` + `/storage/v1`) and the Vite dev server (`/rest/v1` only — the plugin doesn't mount `/storage/v1` by default). `--no-admin` or `supalite({ admin: false })` to disable. Elevation requires keyless + same-origin + loopback socket + loopback hostname. See [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#api-keys). |
99
+ | Email delivery (default templates + customization) | ✅ | - | - | Supabase-styled default HTML, `site_url`-based verify links, GET `/auth/v1/verify` redirect. Override subject + HTML per type via `auth.email.template.<type>.content_path` (GoTrue `{{ .ConfirmationURL }}` etc.). |
100
+ | Email driver (SMTP / provider) | ✅ | - | - | `SmtpEmailDriver` (via Nodemailer) auto-selects when `[auth.email.smtp] enabled = true` in `config.toml` (e.g. pointing at Mailpit or a real SMTP server); `Resend`/`SES`/`Sendmail` remain available via `options.drivers.email`. Default without config or explicit driver is `ConsoleEmailDriver`. `SmtpEmailDriver` requires Node or Bun; not supported on Cloudflare Workers or in the browser. |
101
+ | OAuth / social providers + PKCE (`signInWithOAuth`, `exchangeCodeForSession`) | ⚠️ | `S` per provider | `external-service` | `github` and `google` implemented: authorization-code (PKCE) and implicit flows, automatic account linking. Other configured providers (incl. `apple`) return "not yet implemented"; each is roughly `S` effort, gated on registering a provider app. |
102
+ | Anonymous sign-in (`signInAnonymously`) | 🔄 | `S` | `-` | Create a credential-less user + session. |
103
+ | Admin user API (create/list/get/update/delete, generateLink, signOut) | 🔄 | `M` | `-` | Mostly CRUD over `auth.users`; ~69 skipped spec cases. |
104
+ | Identity linking (`linkIdentity` / `unlinkIdentity`) | 🔄 | `M` | `-` | Automatic linking on OAuth sign-in (verified-email match) already works; the explicit link/unlink API is still planned. Unlink is `S`. |
105
+ | Phone / SMS OTP | 🔄 | `M` | `external-service` | Needs an SMS provider (e.g. Twilio). |
106
+ | MFA / TOTP (enroll, challenge, verify) | 🔄 | `M` | `-` | TOTP via a library (e.g. otplib) + QR; AAL tracking. |
107
+ | `getClaims()` / JWKS verification | 🔄 | `M` | `-` | Fetch + cache JWKS, asymmetric verify. |
108
+ | OIDC ID-token sign-in (`signInWithIdToken`) | 🔄 | `M` | `-` | Validate provider ID token + nonce; lighter than full OAuth handshake. |
109
+ | WebAuthn / passkeys (`mfa.webauthn.*`) | 🔄 | `XL` | `-` | FIDO2/CTAP2 registration + assertion ceremonies; credential storage, signature verification. |
110
+ | OAuth 2.1 authorization server + client admin | 🔄 | `L` | `-` | Lite acting as an OAuth provider: authorization endpoint + client management. |
111
+ | Web3 sign-in (`signInWithWeb3`, SIWE/SIWS) | 🔄 | `L` | `-` | Wallet message + signature verification. |
112
+ | SAML / SSO (`signInWithSSO`) | 🔄 | `XL` | `-` | Enterprise SSO: XML signing, IdP metadata exchange, assertion validation. |
113
+
114
+ ---
115
+
116
+ ## Storage
117
+
118
+ storage-api-compatible endpoints at `/storage/v1/*` (`app/src/storage/`), with pluggable filesystem and S3 backends and Sharp/Cloudflare image transforms. CRUD and signed URLs are done; access control is the main gap. Currently gated behind `EXPERIMENTAL_STORAGE`. Detail in [STATUS.md → Storage API](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#storage-api).
119
+
120
+ | Capability | Status | Effort | Blocker | Notes |
121
+ |------------|:------:|:------:|:-------:|-------|
122
+ | Bucket CRUD (create, list, get, update, delete, empty) | ✅ | - | - | Public/private, file-size limits, allowed MIME types |
123
+ | Object CRUD (upload, replace, download, list, move, copy, remove, info, exists) | ✅ | - | - | Multipart, upsert via `x-upsert`, range requests |
124
+ | Public buckets & public URLs | ✅ | - | - | |
125
+ | Signed URLs (download, batch, upload) | ✅ | - | - | JWT-signed, configurable TTL |
126
+ | Image transformations (resize, format, quality) | ✅ | - | - | Sharp (buffer) and Cloudflare (URL) adapters |
127
+ | Storage backends | ✅ | - | - | Filesystem + S3-compatible (AWS S3, MinIO, R2) |
128
+ | Role-based access (service_role / anon / authenticated gating) | ⚠️ | `M` | `-` | API keys now resolve `service_role`/`anon`/`authenticated` for storage's route-level checks (secret key satisfies authed routes as `service_role`); auth-error format still diverges (401 vs 400), and there's no per-object RLS yet. |
129
+ | RLS policies on storage tables | 🔄 | `M` | `-` | Per-user object access; can reuse the existing `RlsEnforcer`. ~48 `access_control` spec cases depend on it. |
130
+ | `/status` health endpoint | 🔄 | `S` | `-` | Returns 200 without auth. |
131
+ | Bucket-list query params (`search`/`limit`/`offset`) | 🔄 | `S` | `-` | |
132
+ | TUS resumable uploads | 🔄 | `L` | `-` | `POST/PATCH/HEAD /upload/resumable`; spec cases exist, endpoints don't. |
133
+ | S3-compatible protocol paths (`/s3/`) | 🔄 | `L` | `-` | |
134
+ | Webhooks (ObjectCreated/ObjectRemoved) | 🔄 | `M` | `-` | |
135
+
136
+ ---
137
+
138
+ ## Edge Functions
139
+
140
+ Planned, not started. Only config schemas exist (`app/src/config/functions.ts`, `app/src/config/edge_runtime.ts`): per-function `enabled`, `verify_jwt`, `import_map`, `entrypoint`, and runtime `policy`/`inspector_port`. No `/functions/v1/*` routes, no runtime.
141
+
142
+ The client surface is small: `@supabase/functions-js` is essentially one method, `invoke(name, opts)` (plus `constructor`/`setAuth`). The cost is almost entirely server-side, and splits into two layers. **Request/response plumbing** (routing, auth injection, body/content-type handling, streaming, region headers, error classification) is ordinary HTTP work. **The runtime** (executing user TypeScript) is the hard part. Supabase uses a custom Rust/Deno `edge-runtime` with V8 isolates and a main/user worker model. Lite's path is a Web-API-compatible runtime adapter so you can plug in whichever executor fits the host (`vm`/`vm2`/`sval`, dynamic workers, Bun, Deno). This likely depends on Supabase Workers landing, since that runtime targets Node.js.
143
+
144
+ | Capability | Status | Effort | Blocker | Notes |
145
+ |------------|:------:|:------:|:-------:|-------|
146
+ | Invoke routing (`/functions/v1/{name}`), auth + `apikey` injection | 🔄 | `M` | `-` | Proxy mode: forward to an external runtime; reuses existing Hono server + auth. |
147
+ | Per-function JWT verification (`verify_jwt`) | 🔄 | `S` | `-` | Config schema + auth system already exist. |
148
+ | Body / Content-Type handling + response dispatch | 🔄 | `M` | `-` | json / blob / text / formData; auto Content-Type detection. |
149
+ | Streaming responses (SSE passthrough) | 🔄 | `M` | `-` | Return the raw `Response` for `text/event-stream`. |
150
+ | Region routing (`x-region` / `forceFunctionRegion`) | 🔄 | `S` | `-` | Header + query passthrough; no real multi-region locally. |
151
+ | Pluggable runtime (execute user code) | 🔄 | `XL` | `platform-limited` | Web-API-compatible runtime adapter with pluggable executors (`vm`/`vm2`/`sval`, dynamic workers, Bun, Deno) + worker lifecycle (`oneshot`/`per_worker`). Likely depends on Supabase Workers (Node.js-targeted) landing. |
152
+ | Local `functions serve` (dev) + file-watch reload | 🔄 | `L` | `platform-limited` | Depends on the runtime above. |
153
+ | Deployment / management API (deploy, list, get, update, delete, body) | 🔄 | `L` | `-` | ESZip bundling + function registry; lite needs its own tracking (SQLite/config). |
154
+ | Secrets / env injection (`Deno.env`) | 🔄 | `S` | `-` | Inject `SUPABASE_URL`/keys + user secrets. |
155
+ | Database Webhooks (`supabase_functions.hooks`, `http_request` trigger) | 🔄 | `M` | `platform-limited` | Distinct feature: in Postgres, row triggers fire HTTP via `pg_net`. Lite can hook the same events at the app layer (mutations flow through the Data API) and fetch out, avoiding `pg_net`. Caveat: misses out-of-band direct DB writes. |
156
+
157
+ ---
158
+
159
+ ## Realtime
160
+
161
+ Planned, not started. Only a config schema exists (`app/src/config/realtime.ts`: `enabled`, `ip_version`, `max_header_length`). No WebSocket server, no channels.
162
+
163
+ The `@supabase/realtime-js` surface is one channel abstraction (`supabase.channel(...).on(...).subscribe()`) carrying three feature families. **Broadcast** and **Presence** are pure pub/sub over a WebSocket and don't touch the database, so they're tractable once the socket transport exists. **Postgres Changes** is the harder one: Supabase streams it from Postgres logical replication (WAL), which SQLite does not have. Rather than reach for an extension, lite can capture changes at the app layer: every mutation flows through the Data API, so change events can be emitted from there without DB triggers or replication. The tradeoff is that this only sees writes made through lite, not out-of-band writes straight to the database.
164
+
165
+ | Capability | Status | Effort | Blocker | Notes |
166
+ |------------|:------:|:------:|:-------:|-------|
167
+ | WebSocket transport + channel protocol (`/realtime/v1`) | 🔄 | `M` | `-` | Foundation: socket server, Phoenix-style channel join/leave, heartbeat. |
168
+ | Broadcast (ephemeral pub/sub messages) | 🔄 | `M` | `-` | Independent of the database; fan-out to channel subscribers. |
169
+ | Presence (track / sync / join / leave state) | 🔄 | `M` | `-` | Built on the same channel + a per-channel state CRDT. |
170
+ | Channel authorization (private channels / RLS) | 🔄 | `M` | `-` | Reuse the existing RLS engine + JWT to gate join and message access. |
171
+ | Postgres Changes / CDC (`postgres_changes` on INSERT/UPDATE/DELETE) | 🔄 | `L` | `platform-limited` | No SQLite logical replication. Capture changes at the app layer (all mutations flow through the Data API), avoiding extensions and DB triggers. Caveat: only catches writes made through lite, not out-of-band direct DB writes. |
172
+ | Broadcast-from-database (`realtime.broadcast_changes`) | 🔄 | `L` | `platform-limited` | Same app-layer change capture as CDC; emits broadcast messages from row changes. |
173
+
174
+ ---
175
+
176
+ > Maintenance: update this file alongside [STATUS.md](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md) whenever feature support changes. Statuses here must agree with STATUS.md; this doc only adds the effort/blocker lens, it never overrides a support verdict. See [AGENTS.md](https://github.com/supabase-community/lite/blob/HEAD/AGENTS.md).
package/LIMITATIONS.md CHANGED
@@ -6,6 +6,7 @@ Anchors below point to the corresponding STATUS.md section. If a limitation here
6
6
 
7
7
  ## SQL / DDL (SQLite path)
8
8
 
9
+ - Extension declarations are no-ops only for `plpgsql`, `pgcrypto`, and `uuid-ossp`; schema moves and drops for those names are ignored for declarative convergence, while unsupported names and other mutations fail. Only the documented PL/pgSQL trigger subset and UUID v4 defaults are emulated. See [Extension Statements](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#extension-statements).
9
10
  - `DEFAULT auth.uid()` (and `auth.role()`, `auth.email()`, `auth.jwt()`) on columns → not supported. Drop the default, pass `user_id` from the client, rely on RLS `WITH CHECK`. See [Column Defaults](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#column-defaults).
10
11
  - Subquery `WITH CHECK` on `INSERT` (`user_id IN (SELECT …)`, `EXISTS (…)`) → throws. Denormalise the owning column. See [RLS known limitations](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#row-level-security-rls).
11
12
  - Scalar functions outside the allow-list in `DEFAULT` or `CHECK` (`trim`, `btrim`, `length`, `lower`, `upper`, …) → `Function call "<name>" not supported`. Use literals or move the check to the app layer. See [Column Defaults](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#column-defaults) and [CHECK constraint functions](https://github.com/supabase-community/lite/blob/HEAD/STATUS.md#check-constraint-functions).
package/README.md CHANGED
@@ -24,6 +24,7 @@ If you're an agent working on a supalite project, read these first:
24
24
 
25
25
  - [`LIMITATIONS.md`](https://github.com/supabase-community/lite/blob/HEAD/LIMITATIONS.md) — what's unsupported / partial, plus anti-patterns. Token-efficient cheat sheet.
26
26
  - [`PATTERNS.md`](https://github.com/supabase-community/lite/blob/HEAD/PATTERNS.md) — canonical recipes (per-user RLS, embedded filter workarounds, custom server logic, Vite cold start, triggers).
27
+ - The full product documentation, shipped in the package at `node_modules/@supabase/lite/docs/` (index: `llms.txt`) and published at [docs.lite.dev](https://docs.lite.dev).
27
28
 
28
29
  The npm package ships a [`supalite` skill](https://github.com/supabase-community/lite/blob/HEAD/skills/supalite/SKILL.md). After `npm install`, link it into your agent's skills dir so the cold-start checklist, routing rule, and limitation pointers trigger automatically:
29
30
 
package/STATUS.md CHANGED
@@ -36,7 +36,7 @@ Feature and API compatibility tracking for @supabase/lite. For usage docs, see [
36
36
 
37
37
  When using SQLite databases, SQL schemas written in Postgres dialect are translated on the fly. The translator extends the Postgres deparser. It passes through 1:1 compatible syntax unchanged, rewrites constructs that have SQLite equivalents (for example `SERIAL` → `INTEGER PRIMARY KEY AUTOINCREMENT`, `NOW()` → `datetime('now')`), silently drops Postgres-only decorators and relation/schema privilege metadata (storage parameters, locking clauses, table/schema/sequence grants), and errors on features that have no SQLite counterpart (`LATERAL` joins, table inheritance, function grants).
38
38
 
39
- 📋 See [`app/POSTGRES-SQLITE-COMPAT.md`](https://github.com/supabase-community/lite/blob/HEAD/app/POSTGRES-SQLITE-COMPAT.md) for the full auto-generated compatibility reference (71 entries).
39
+ 📋 See [`app/POSTGRES-SQLITE-COMPAT.md`](https://github.com/supabase-community/lite/blob/HEAD/app/POSTGRES-SQLITE-COMPAT.md) for the full auto-generated compatibility reference (74 entries).
40
40
 
41
41
  Here is an example of a Postgres schema that is translated to SQLite:
42
42
 
@@ -130,6 +130,12 @@ CREATE TABLE orders
130
130
  -- RLS statements not emitted
131
131
  ```
132
132
 
133
+ ### Extension Statements
134
+
135
+ On the SQLite translation path, `CREATE EXTENSION` is accepted only for `plpgsql`, `pgcrypto`, and `uuid-ossp`, then omitted from the emitted DDL. The `plpgsql` declaration is accepted for `pg_dump` schema compatibility; PL/pgSQL support remains limited to the documented trigger-function subset. The UUID declarations allow migrations that use the supported `gen_random_uuid()` and `uuid_generate_v4()` defaults to run, but no other extension APIs are provided. Valid creation modifiers such as `IF NOT EXISTS`, `WITH SCHEMA`, `VERSION`, and `CASCADE` are accepted for those three exact names; quoted names remain case-sensitive.
136
+
137
+ To keep declarative `db diff` state convergent, `ALTER EXTENSION <accepted-name> SET SCHEMA ...` and `DROP EXTENSION` containing only accepted names are also omitted. Every other `CREATE EXTENSION`, all extension updates/member changes, schema moves for unsupported extensions, and drops containing an unsupported name fail during translation before any statement in that migration is executed. PGlite and PostgreSQL run extension statements natively; the bare `sqlite` driver does not translate PostgreSQL DDL.
138
+
133
139
  ### Translated Field Types
134
140
 
135
141
  | PostgreSQL type / syntax | SQLite storage | Field implementation | Mapping / validation |