orez 0.0.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 (47) hide show
  1. package/README.md +116 -0
  2. package/dist/config.d.ts +15 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +20 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/index.d.ts +15 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +195 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/pg-proxy.d.ts +14 -0
  11. package/dist/pg-proxy.d.ts.map +1 -0
  12. package/dist/pg-proxy.js +385 -0
  13. package/dist/pg-proxy.js.map +1 -0
  14. package/dist/pglite-manager.d.ts +5 -0
  15. package/dist/pglite-manager.d.ts.map +1 -0
  16. package/dist/pglite-manager.js +71 -0
  17. package/dist/pglite-manager.js.map +1 -0
  18. package/dist/replication/change-tracker.d.ts +14 -0
  19. package/dist/replication/change-tracker.d.ts.map +1 -0
  20. package/dist/replication/change-tracker.js +86 -0
  21. package/dist/replication/change-tracker.js.map +1 -0
  22. package/dist/replication/handler.d.ts +24 -0
  23. package/dist/replication/handler.d.ts.map +1 -0
  24. package/dist/replication/handler.js +300 -0
  25. package/dist/replication/handler.js.map +1 -0
  26. package/dist/replication/pgoutput-encoder.d.ts +26 -0
  27. package/dist/replication/pgoutput-encoder.d.ts.map +1 -0
  28. package/dist/replication/pgoutput-encoder.js +204 -0
  29. package/dist/replication/pgoutput-encoder.js.map +1 -0
  30. package/dist/s3-local.d.ts +8 -0
  31. package/dist/s3-local.d.ts.map +1 -0
  32. package/dist/s3-local.js +131 -0
  33. package/dist/s3-local.js.map +1 -0
  34. package/package.json +56 -0
  35. package/src/config.ts +40 -0
  36. package/src/index.ts +255 -0
  37. package/src/pg-proxy.ts +474 -0
  38. package/src/pglite-manager.ts +105 -0
  39. package/src/replication/change-tracker.test.ts +179 -0
  40. package/src/replication/change-tracker.ts +115 -0
  41. package/src/replication/handler.test.ts +331 -0
  42. package/src/replication/handler.ts +378 -0
  43. package/src/replication/pgoutput-encoder.test.ts +381 -0
  44. package/src/replication/pgoutput-encoder.ts +252 -0
  45. package/src/replication/tcp-replication.test.ts +824 -0
  46. package/src/replication/zero-compat.test.ts +882 -0
  47. package/src/s3-local.ts +179 -0
package/README.md ADDED
@@ -0,0 +1,116 @@
1
+ # orez
2
+
3
+ Drop-in replacement for the Docker-based development backend that Rocicorp's Zero requires. Instead of running PostgreSQL, zero-cache, and MinIO in Docker containers, orez bundles everything into a single process using PGlite (PostgreSQL compiled to WASM).
4
+
5
+ The goal is simple: `bun install && bun dev` with zero system dependencies.
6
+
7
+
8
+ ## How it works
9
+
10
+ orez starts four things in one process:
11
+
12
+ 1. A PGlite instance (full PostgreSQL 16 running in-process via WASM)
13
+ 2. A TCP proxy that speaks the PostgreSQL wire protocol, including logical replication
14
+ 3. A zero-cache child process that connects to the proxy thinking it's a real Postgres server
15
+ 4. A minimal S3-compatible HTTP server for file uploads
16
+
17
+ The trick is in the TCP proxy. zero-cache needs logical replication to stay in sync with the upstream database. PGlite doesn't support logical replication natively, so orez fakes it. Every mutation is captured by triggers into a changes table, then encoded into the pgoutput binary protocol and streamed to zero-cache through the replication connection. zero-cache can't tell the difference.
18
+
19
+ The proxy also handles multi-database routing. zero-cache expects three separate databases (upstream, CVR, change), but PGlite is a single database. orez maps database names to schemas, so `zero_cvr` becomes the `zero_cvr` schema and `zero_cdb` becomes `zero_cdb`.
20
+
21
+
22
+ ## Install
23
+
24
+ ```
25
+ npm install orez
26
+ ```
27
+
28
+ or with bun:
29
+
30
+ ```
31
+ bun add orez
32
+ ```
33
+
34
+ You also need `@rocicorp/zero` installed in your project for the zero-cache binary.
35
+
36
+
37
+ ## Usage
38
+
39
+ ```typescript
40
+ import { startZeroLite } from 'orez'
41
+
42
+ const { config, stop } = await startZeroLite({
43
+ pgPort: 6434,
44
+ zeroPort: 5849,
45
+ s3Port: 10201,
46
+ migrationsDir: 'src/database/migrations',
47
+ seedFile: 'src/database/seed.sql',
48
+ })
49
+
50
+ // your app connects to zero-cache at localhost:5849
51
+ // database is at postgresql://user:password@localhost:6434/postgres
52
+
53
+ // when done
54
+ await stop()
55
+ ```
56
+
57
+ All options are optional and have sensible defaults. See `src/config.ts` for the full list.
58
+
59
+
60
+ ## What gets faked
61
+
62
+ The proxy intercepts several things to convince zero-cache it's talking to a real PostgreSQL server with logical replication enabled:
63
+
64
+ - `IDENTIFY_SYSTEM` returns a fake system ID and timeline
65
+ - `CREATE_REPLICATION_SLOT` persists slot info in a local table and returns a valid LSN
66
+ - `START_REPLICATION` enters streaming mode, encoding changes as pgoutput binary messages
67
+ - `current_setting('wal_level')` always returns `logical`
68
+ - `pg_replication_slots` queries are redirected to a local tracking table
69
+ - `SET TRANSACTION SNAPSHOT` is silently accepted (PGlite doesn't support imported snapshots)
70
+ - `ALTER ROLE ... REPLICATION` returns success
71
+ - `READ ONLY` is stripped from transaction starts to avoid PGlite serialization issues
72
+
73
+ The pgoutput encoder produces spec-compliant binary messages: Begin, Relation, Insert, Update, Delete, Commit, and Keepalive. All column values are encoded as text (typeOid 25), which zero-cache handles fine since it re-maps types downstream anyway.
74
+
75
+
76
+ ## Tests
77
+
78
+ 80 unit tests across 5 test files covering the full stack from binary encoding to TCP-level integration:
79
+
80
+ ```
81
+ bun test
82
+ ```
83
+
84
+ The test suite includes a zero-cache compatibility layer that decodes pgoutput messages into the same typed format that zero-cache's PgoutputParser produces, validating end-to-end compatibility.
85
+
86
+
87
+ ## Limitations
88
+
89
+ This is a development tool. It is not suitable for production use.
90
+
91
+ - PGlite runs single-threaded. All queries are serialized through a mutex. This is fine for development but would be a bottleneck under real load.
92
+ - Column types are all encoded as text in the replication stream. Zero-cache handles this, but other pgoutput consumers might not.
93
+ - Triggers add overhead to every write. Again, fine for development.
94
+ - PGlite stores data on the local filesystem. No replication, no backups, no high availability.
95
+ - The S3 server is just a filesystem wrapper. No multipart uploads, no ACLs, no versioning.
96
+
97
+
98
+ ## Project structure
99
+
100
+ ```
101
+ src/
102
+ index.ts main entry, orchestrates startup
103
+ config.ts configuration with defaults
104
+ pg-proxy.ts tcp proxy with query rewriting
105
+ pglite-manager.ts pglite instance and migration runner
106
+ s3-local.ts minimal s3 http server
107
+ replication/
108
+ handler.ts replication protocol state machine
109
+ pgoutput-encoder.ts binary pgoutput message encoder
110
+ change-tracker.ts trigger installation and change reader
111
+ ```
112
+
113
+
114
+ ## License
115
+
116
+ MIT
@@ -0,0 +1,15 @@
1
+ export interface ZeroLiteConfig {
2
+ dataDir: string;
3
+ pgPort: number;
4
+ zeroPort: number;
5
+ s3Port: number;
6
+ webPort: number;
7
+ pgUser: string;
8
+ pgPassword: string;
9
+ migrationsDir: string;
10
+ seedFile: string;
11
+ skipZeroCache: boolean;
12
+ }
13
+ export declare function getConfig(overrides?: Partial<ZeroLiteConfig>): ZeroLiteConfig;
14
+ export declare function getConnectionString(config: ZeroLiteConfig, dbName?: string): string;
15
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,wBAAgB,SAAS,CACvB,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM,GACtC,cAAc,CAiBhB;AAED,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,cAAc,EACtB,MAAM,SAAa,GAClB,MAAM,CAER"}
package/dist/config.js ADDED
@@ -0,0 +1,20 @@
1
+ export function getConfig(overrides = {}) {
2
+ return {
3
+ dataDir: overrides.dataDir || '.zero-lite',
4
+ pgPort: overrides.pgPort || 6434,
5
+ zeroPort: overrides.zeroPort || 5849,
6
+ s3Port: overrides.s3Port || 10201,
7
+ webPort: overrides.webPort ||
8
+ Number(process.env.VITE_PORT_WEB) ||
9
+ 8081,
10
+ pgUser: overrides.pgUser || 'user',
11
+ pgPassword: overrides.pgPassword || 'password',
12
+ migrationsDir: overrides.migrationsDir || 'src/database/migrations',
13
+ seedFile: overrides.seedFile || 'src/database/seed.sql',
14
+ skipZeroCache: overrides.skipZeroCache || false,
15
+ };
16
+ }
17
+ export function getConnectionString(config, dbName = 'postgres') {
18
+ return `postgresql://${config.pgUser}:${config.pgPassword}@127.0.0.1:${config.pgPort}/${dbName}`;
19
+ }
20
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAaA,MAAM,UAAU,SAAS,CACvB,YAAqC,EAAE;IAEvC,OAAO;QACL,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,YAAY;QAC1C,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,IAAI;QAChC,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,IAAI;QACpC,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,KAAK;QACjC,OAAO,EACL,SAAS,CAAC,OAAO;YACjB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;YACjC,IAAI;QACN,MAAM,EAAE,SAAS,CAAC,MAAM,IAAI,MAAM;QAClC,UAAU,EAAE,SAAS,CAAC,UAAU,IAAI,UAAU;QAC9C,aAAa,EACX,SAAS,CAAC,aAAa,IAAI,yBAAyB;QACtD,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,uBAAuB;QACvD,aAAa,EAAE,SAAS,CAAC,aAAa,IAAI,KAAK;KAChD,CAAA;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,MAAsB,EACtB,MAAM,GAAG,UAAU;IAEnB,OAAO,gBAAgB,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,cAAc,MAAM,CAAC,MAAM,IAAI,MAAM,EAAE,CAAA;AAClG,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * orez: pglite-powered zero-sync development backend.
3
+ *
4
+ * starts a pglite instance, tcp proxy, s3 server, and zero-cache
5
+ * process. replaces docker-based postgresql, zero-cache, and minio
6
+ * with a single `bun run` command.
7
+ */
8
+ import type { ZeroLiteConfig } from './config';
9
+ export type { ZeroLiteConfig } from './config';
10
+ export { getConfig, getConnectionString } from './config';
11
+ export declare function startZeroLite(overrides?: Partial<ZeroLiteConfig>): Promise<{
12
+ config: ZeroLiteConfig;
13
+ stop: () => Promise<void>;
14
+ }>;
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsBH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE9C,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAEzD,wBAAsB,aAAa,CAAC,SAAS,GAAE,OAAO,CAAC,cAAc,CAAM;;;GAoD1E"}
package/dist/index.js ADDED
@@ -0,0 +1,195 @@
1
+ /**
2
+ * orez: pglite-powered zero-sync development backend.
3
+ *
4
+ * starts a pglite instance, tcp proxy, s3 server, and zero-cache
5
+ * process. replaces docker-based postgresql, zero-cache, and minio
6
+ * with a single `bun run` command.
7
+ */
8
+ import { resolve, join } from 'node:path';
9
+ import { existsSync, readFileSync, mkdirSync, writeFileSync, unlinkSync, } from 'node:fs';
10
+ import { spawn } from 'node:child_process';
11
+ import { getConfig, getConnectionString } from './config';
12
+ import { installChangeTracking } from './replication/change-tracker';
13
+ import { createPGliteInstance, runMigrations } from './pglite-manager';
14
+ import { startPgProxy } from './pg-proxy';
15
+ import { startS3Server } from './s3-local';
16
+ export { getConfig, getConnectionString } from './config';
17
+ export async function startZeroLite(overrides = {}) {
18
+ const config = getConfig(overrides);
19
+ console.info('[orez] starting...');
20
+ console.info(`[orez] data dir: ${resolve(config.dataDir)}`);
21
+ mkdirSync(config.dataDir, { recursive: true });
22
+ // start pglite
23
+ const db = await createPGliteInstance(config);
24
+ // run migrations
25
+ await runMigrations(db, config);
26
+ // install change tracking
27
+ console.info('[orez] installing change tracking');
28
+ await installChangeTracking(db);
29
+ // start tcp proxy
30
+ const pgServer = await startPgProxy(db, config);
31
+ // start s3 server
32
+ const s3Server = await startS3Server(config);
33
+ // seed data if needed
34
+ await seedIfNeeded(db, config);
35
+ // write .env.local so `bun dev` connects to orez ports
36
+ writeEnvLocal(config);
37
+ // start zero-cache
38
+ let zeroCacheProcess = null;
39
+ if (!config.skipZeroCache) {
40
+ console.info('[orez] starting zero-cache...');
41
+ zeroCacheProcess = await startZeroCache(config);
42
+ await waitForZeroCache(config);
43
+ }
44
+ else {
45
+ console.info('[orez] skipping zero-cache (skipZeroCache=true)');
46
+ }
47
+ const stop = async () => {
48
+ console.info('[orez] shutting down...');
49
+ if (zeroCacheProcess) {
50
+ zeroCacheProcess.kill('SIGTERM');
51
+ }
52
+ pgServer.close();
53
+ s3Server.close();
54
+ await db.close();
55
+ cleanupEnvLocal();
56
+ console.info('[orez] stopped');
57
+ };
58
+ return { config, stop };
59
+ }
60
+ const ENV_LOCAL_PATH = resolve('.env.local');
61
+ const ENV_LOCAL_MARKER = '# auto-generated by orez';
62
+ function writeEnvLocal(config) {
63
+ const upstreamUrl = getConnectionString(config, 'postgres');
64
+ const cvrUrl = getConnectionString(config, 'zero_cvr');
65
+ const cdbUrl = getConnectionString(config, 'zero_cdb');
66
+ const content = `${ENV_LOCAL_MARKER}
67
+ VITE_PORT_POSTGRES=${config.pgPort}
68
+ VITE_PORT_ZERO=${config.zeroPort}
69
+ VITE_PORT_MINIO=${config.s3Port}
70
+ VITE_PUBLIC_ZERO_SERVER="http://localhost:${config.zeroPort}"
71
+ ZERO_UPSTREAM_DB="${upstreamUrl}"
72
+ ZERO_CVR_DB="${cvrUrl}"
73
+ ZERO_CHANGE_DB="${cdbUrl}"
74
+ CLOUDFLARE_R2_ENDPOINT="http://localhost:${config.s3Port}"
75
+ CLOUDFLARE_R2_PUBLIC_URL="http://localhost:${config.s3Port}"
76
+ `;
77
+ writeFileSync(ENV_LOCAL_PATH, content);
78
+ console.info('[orez] wrote .env.local for dev server');
79
+ }
80
+ function cleanupEnvLocal() {
81
+ try {
82
+ if (existsSync(ENV_LOCAL_PATH)) {
83
+ const content = readFileSync(ENV_LOCAL_PATH, 'utf-8');
84
+ if (content.startsWith(ENV_LOCAL_MARKER)) {
85
+ unlinkSync(ENV_LOCAL_PATH);
86
+ console.info('[orez] cleaned up .env.local');
87
+ }
88
+ }
89
+ }
90
+ catch {
91
+ // ignore cleanup errors
92
+ }
93
+ }
94
+ async function seedIfNeeded(db, config) {
95
+ // check if we already have data
96
+ try {
97
+ const result = await db.query('SELECT count(*) as count FROM public."user"');
98
+ if (Number(result.rows[0].count) > 0) {
99
+ return;
100
+ }
101
+ }
102
+ catch {
103
+ // table might not exist yet
104
+ }
105
+ console.info('[orez] seeding demo data...');
106
+ const seedFile = resolve(config.seedFile);
107
+ if (!existsSync(seedFile)) {
108
+ console.info('[orez] no seed file found, skipping');
109
+ return;
110
+ }
111
+ const sql = readFileSync(seedFile, 'utf-8');
112
+ const statements = sql
113
+ .split('--> statement-breakpoint')
114
+ .map((s) => s.trim())
115
+ .filter(Boolean);
116
+ for (const stmt of statements) {
117
+ await db.exec(stmt);
118
+ }
119
+ console.info('[orez] seeded demo data');
120
+ }
121
+ async function startZeroCache(config) {
122
+ // find zero-cache binary
123
+ const zeroCachePaths = [
124
+ resolve('node_modules/.bin/zero-cache'),
125
+ resolve('node_modules/@rocicorp/zero/out/zero-cache/src/bin/main.js'),
126
+ ];
127
+ let zeroCacheBin = '';
128
+ for (const p of zeroCachePaths) {
129
+ if (existsSync(p)) {
130
+ zeroCacheBin = p;
131
+ break;
132
+ }
133
+ }
134
+ if (!zeroCacheBin) {
135
+ throw new Error('zero-cache binary not found. install @rocicorp/zero');
136
+ }
137
+ const upstreamUrl = getConnectionString(config, 'postgres');
138
+ const cvrUrl = getConnectionString(config, 'zero_cvr');
139
+ const cdbUrl = getConnectionString(config, 'zero_cdb');
140
+ const env = {
141
+ ...process.env,
142
+ NODE_ENV: 'development',
143
+ ZERO_UPSTREAM_DB: upstreamUrl,
144
+ ZERO_CVR_DB: cvrUrl,
145
+ ZERO_CHANGE_DB: cdbUrl,
146
+ ZERO_REPLICA_FILE: resolve(config.dataDir, 'zero-replica.db'),
147
+ ZERO_PORT: String(config.zeroPort),
148
+ ZERO_MUTATE_URL: `http://localhost:${config.webPort}/api/zero/push`,
149
+ ZERO_QUERY_URL: `http://localhost:${config.webPort}/api/zero/pull`,
150
+ ZERO_LOG_LEVEL: 'info',
151
+ ZERO_NUM_SYNC_WORKERS: '1',
152
+ DO_NOT_TRACK: '1',
153
+ };
154
+ const child = spawn(zeroCacheBin, [], {
155
+ env,
156
+ stdio: ['ignore', 'pipe', 'pipe'],
157
+ });
158
+ child.stdout?.on('data', (data) => {
159
+ const lines = data.toString().trim().split('\n');
160
+ for (const line of lines) {
161
+ console.info(`[zero-cache] ${line}`);
162
+ }
163
+ });
164
+ child.stderr?.on('data', (data) => {
165
+ const lines = data.toString().trim().split('\n');
166
+ for (const line of lines) {
167
+ console.info(`[zero-cache] ${line}`);
168
+ }
169
+ });
170
+ child.on('exit', (code) => {
171
+ if (code !== 0 && code !== null) {
172
+ console.info(`[zero-cache] exited with code ${code}`);
173
+ }
174
+ });
175
+ return child;
176
+ }
177
+ async function waitForZeroCache(config, timeoutMs = 60000) {
178
+ const start = Date.now();
179
+ const url = `http://127.0.0.1:${config.zeroPort}/`;
180
+ while (Date.now() - start < timeoutMs) {
181
+ try {
182
+ const res = await fetch(url);
183
+ if (res.ok) {
184
+ console.info('[orez] zero-cache is ready');
185
+ return;
186
+ }
187
+ }
188
+ catch {
189
+ // not ready yet
190
+ }
191
+ await new Promise((r) => setTimeout(r, 500));
192
+ }
193
+ console.info('[orez] warning: zero-cache health check timed out, continuing anyway');
194
+ }
195
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * tcp proxy that makes pglite speak postgresql wire protocol.
3
+ *
4
+ * uses pg-gateway to handle protocol lifecycle for regular connections,
5
+ * and directly handles the raw socket for replication connections.
6
+ *
7
+ * regular connections: forwarded to pglite via execProtocolRaw()
8
+ * replication connections: intercepted, replication protocol faked
9
+ */
10
+ import { type Server } from 'node:net';
11
+ import type { PGlite } from '@electric-sql/pglite';
12
+ import type { ZeroLiteConfig } from './config';
13
+ export declare function startPgProxy(db: PGlite, config: ZeroLiteConfig): Promise<Server>;
14
+ //# sourceMappingURL=pg-proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pg-proxy.d.ts","sourceRoot":"","sources":["../src/pg-proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAgB,KAAK,MAAM,EAAe,MAAM,UAAU,CAAA;AAIjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAA;AAElD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAgR9C,wBAAsB,YAAY,CAChC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,MAAM,CAAC,CAoHjB"}