diff --git a/examples/basic/package-lock.json b/examples/basic/package-lock.json
index b079d152..d5e8b5a9 100644
--- a/examples/basic/package-lock.json
+++ b/examples/basic/package-lock.json
@@ -19,15 +19,15 @@
}
},
"../..": {
- "version": "0.2.0",
+ "version": "0.3.1",
"dependencies": {
- "camelcase": "^9.0.0",
- "capnweb": "file:packages/capnweb"
+ "camelcase": "^9.0.0"
},
"bin": {
"tg": "dist/cli.mjs"
},
"devDependencies": {
+ "@cloudflare/vitest-pool-workers": "^0.18.6",
"@electric-sql/pglite": "^0.5.4",
"@eslint/js": "^10.0.1",
"@standard-schema/spec": "^1.1.0",
@@ -41,6 +41,7 @@
"@typescript/native-preview": "7.0.0-dev.20260707.2",
"acorn": "^8.17.0",
"better-sqlite3": "^12.11.1",
+ "capnweb": "file:packages/capnweb",
"eslint": "^10.7.0",
"fast-check": "^4.9.0",
"pg": "^8.22.0",
@@ -56,13 +57,17 @@
"node": ">=22"
},
"peerDependencies": {
- "@electric-sql/pglite": "^0.4.4",
+ "@electric-sql/pglite": "^0.4.4 || ^0.5.0",
+ "better-sqlite3": "^12.11.1 || ^13.0.0",
"pg": "^8.20.0"
},
"peerDependenciesMeta": {
"@electric-sql/pglite": {
"optional": true
},
+ "better-sqlite3": {
+ "optional": true
+ },
"pg": {
"optional": true
}
diff --git a/examples/chat/package-lock.json b/examples/chat/package-lock.json
index 5a125ef5..5d081138 100644
--- a/examples/chat/package-lock.json
+++ b/examples/chat/package-lock.json
@@ -30,7 +30,7 @@
}
},
"../..": {
- "version": "0.2.0",
+ "version": "0.3.1",
"dependencies": {
"camelcase": "^9.0.0"
},
@@ -68,8 +68,8 @@
"node": ">=22"
},
"peerDependencies": {
- "@electric-sql/pglite": "^0.4.4",
- "better-sqlite3": "^12.11.1",
+ "@electric-sql/pglite": "^0.4.4 || ^0.5.0",
+ "better-sqlite3": "^12.11.1 || ^13.0.0",
"pg": "^8.20.0"
},
"peerDependenciesMeta": {
@@ -84,26 +84,6 @@
}
}
},
- "../../packages/capnweb": {
- "version": "0.6.1",
- "extraneous": true,
- "license": "MIT",
- "devDependencies": {
- "@changesets/changelog-github": "^0.5.2",
- "@changesets/cli": "^2.29.8",
- "@cloudflare/vitest-pool-workers": "^0.12.10",
- "@cloudflare/workers-types": "^4.20260205.0",
- "@types/ws": "^8.18.1",
- "@vitest/browser": "^3.2.4",
- "pkg-pr-new": "^0.0.60",
- "playwright": "^1.56.1",
- "tsup": "^8.5.1",
- "tsx": "^4.21.0",
- "typescript": "^5.9.3",
- "vitest": "^3.2.4",
- "ws": "^8.19.0"
- }
- },
"node_modules/@babel/code-frame": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
diff --git a/examples/sqlite/package-lock.json b/examples/sqlite/package-lock.json
index 8c446354..7f371552 100644
--- a/examples/sqlite/package-lock.json
+++ b/examples/sqlite/package-lock.json
@@ -19,15 +19,15 @@
}
},
"../..": {
- "version": "0.2.0",
+ "version": "0.3.1",
"dependencies": {
- "camelcase": "^9.0.0",
- "capnweb": "file:packages/capnweb"
+ "camelcase": "^9.0.0"
},
"bin": {
"tg": "dist/cli.mjs"
},
"devDependencies": {
+ "@cloudflare/vitest-pool-workers": "^0.18.6",
"@electric-sql/pglite": "^0.5.4",
"@eslint/js": "^10.0.1",
"@standard-schema/spec": "^1.1.0",
@@ -41,6 +41,7 @@
"@typescript/native-preview": "7.0.0-dev.20260707.2",
"acorn": "^8.17.0",
"better-sqlite3": "^12.11.1",
+ "capnweb": "file:packages/capnweb",
"eslint": "^10.7.0",
"fast-check": "^4.9.0",
"pg": "^8.22.0",
@@ -56,13 +57,17 @@
"node": ">=22"
},
"peerDependencies": {
- "@electric-sql/pglite": "^0.4.4",
+ "@electric-sql/pglite": "^0.4.4 || ^0.5.0",
+ "better-sqlite3": "^12.11.1 || ^13.0.0",
"pg": "^8.20.0"
},
"peerDependenciesMeta": {
"@electric-sql/pglite": {
"optional": true
},
+ "better-sqlite3": {
+ "optional": true
+ },
"pg": {
"optional": true
}
diff --git a/site/src/layouts/BaseLayout.astro b/site/src/layouts/BaseLayout.astro
index f47a359b..5d785e94 100644
--- a/site/src/layouts/BaseLayout.astro
+++ b/site/src/layouts/BaseLayout.astro
@@ -7,8 +7,8 @@ interface Props {
}
const {
- title = "Typegres — Postgres tables as classes. Methods are your API.",
- description = "Wrap Postgres tables in TypeScript classes. Mark methods exposed; clients compose typed queries against them — no routes, no GraphQL, no auto-CRUD.",
+ title = "Typegres: Postgres tables as classes. Methods are your API.",
+ description = "Wrap Postgres tables in TypeScript classes. Mark methods exposed; clients compose typed queries against them. No routes, no GraphQL, no auto-CRUD.",
} = Astro.props;
---
diff --git a/site/src/pages/_HomePage.tsx b/site/src/pages/_HomePage.tsx
index eb70623c..bdb468fe 100644
--- a/site/src/pages/_HomePage.tsx
+++ b/site/src/pages/_HomePage.tsx
@@ -25,7 +25,7 @@ export default function HomePage() {
title: "1. Decouple Your Interface from Your Schema - With All of Postgres, Fully Typed",
description:
'Wrap your tables in a stable, public interface. You can refactor your "private" tables and columns without ever breaking clients.',
- leftCode: `class User extends Table("users") {
+ leftCode: `class User extends db.Table("users") {
// ...
// Your public interface stays stable as your schema evolves
@@ -48,8 +48,8 @@ const latest = await User.from()
{
title: "2. Your Interface Defines Your Data Boundaries",
description:
- "Allowed operations are just methods on your interface, including relations and mutations. Everything fully composable and typed.",
- leftCode: `class User extends Table("users") {
+ "Allowed operations are just methods on your interface, including relations and mutations. Everything fully composable and typed. This is encapsulation 101, applied to your tables.",
+ leftCode: `class User extends db.Table("users") {
// ...
todos() {
@@ -57,7 +57,7 @@ const latest = await User.from()
}
}
-class Todo extends Table("todos") {
+class Todo extends db.Table("todos") {
// ...
update(fields: { completed?: boolean; title?: string }) {
@@ -89,9 +89,7 @@ await todo.update({ completed: true }).execute(db);`,
}
class Api {
- @expose() db = db;
-
- // Server-validated entry point — clients compose against this:
+ // Server-validated entry point. Clients compose against this:
@expose(z.string())
forToken(token: string) {
return User.from()
@@ -99,19 +97,25 @@ class Api {
}
}
-export const client = new RpcClient
+ $
+ npm i typegres
+
+
+ Full instructions
+ - Experience the power of composable, capability-first database queries with full type safety and - AI-native architecture. + The playground runs Postgres in your browser via PGlite (no signup, no server) against a real + demo schema. Typegres is pre-1.0 and not recommended for production workloads yet.
+ Postgres and SQLite. Both surfaces are code-generated from the engine itself: Postgres from its + catalog, SQLite from its documented functions. Each dialect gets its own real functions and + operators rather than a lowest-common-denominator abstraction over both. +
++ Drivers: node-postgres and PGlite (WASM Postgres, which the playground on this site runs on) for + Postgres; better-sqlite3 and Cloudflare Durable Object storage for SQLite. +
++ tRPC removes most endpoint boilerplate, but it doesn't compose: the client can only call + procedures that already exist. +
++ So every new question is another procedure: join these two datasets, filter on something nobody + anticipated, aggregate differently. Typegres pushes the composition itself to the server, so the + client asks a new question without you shipping a new endpoint. +
+- A highly constrained interpreter that evaluates untrusted code (the same shape as - {" "}codemode for AI agents), inspired by{" "} Cap'n Web - - . The client serializes a closure that composes over a set of classes/methods, and the - server evaluates it in a single RPC call. There's also a{" "} + {" "} + is the transport, giving you capabilities, promise pipelining and live subscriptions over a + single WebSocket. The client serializes a closure that composes over the classes and methods you + exposed, and the server evaluates it against that surface in a single RPC call. Cap'n Web + ships bundled with Typegres until{" "} - PR + this PR {" "} - in flight to make Cap'n Web itself work as a transport for Typegres. + lands upstream.
+ The shape is close to GraphQL: the relations you define form a graph, and clients traverse it from + a root capability, usually the row representing the current user. The difference is what they can + do once they're inside those boundaries. GraphQL clients traverse edges; Typegres clients get + the database itself: joins, aggregations, and every builtin function and operator. +
- This is a research preview and not ready for production use. Try the{" "} + Pre-1.0. Published on npm and usable today, but not recommended for production workloads yet. + Try the{" "} ; // Iterate explicitly so we can hold the iterator handle for diff --git a/site/src/pages/_PlayPageInner.tsx b/site/src/pages/_PlayPageInner.tsx index b7683fe3..01fe9133 100644 --- a/site/src/pages/_PlayPageInner.tsx +++ b/site/src/pages/_PlayPageInner.tsx @@ -221,7 +221,7 @@ declare function output(value: unknown): void;