pgserve 0.1.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 (158) hide show
  1. package/.genie/AGENTS.md +13 -0
  2. package/.genie/agents/README.md +110 -0
  3. package/.genie/agents/analyze.md +176 -0
  4. package/.genie/agents/forge.md +290 -0
  5. package/.genie/agents/garbage-cleaner.md +324 -0
  6. package/.genie/agents/garbage-collector.md +596 -0
  7. package/.genie/agents/github-issue-gc.md +618 -0
  8. package/.genie/agents/review.md +380 -0
  9. package/.genie/agents/semantic-analyzer/find-duplicates.md +90 -0
  10. package/.genie/agents/semantic-analyzer/find-orphans.md +99 -0
  11. package/.genie/agents/semantic-analyzer.md +101 -0
  12. package/.genie/agents/update.md +182 -0
  13. package/.genie/agents/wish.md +357 -0
  14. package/.genie/code/AGENTS.md +692 -0
  15. package/.genie/code/agents/audit/risk.md +173 -0
  16. package/.genie/code/agents/audit/security.md +189 -0
  17. package/.genie/code/agents/audit.md +145 -0
  18. package/.genie/code/agents/challenge.md +230 -0
  19. package/.genie/code/agents/change-reviewer.md +295 -0
  20. package/.genie/code/agents/code-garbage-collector.md +425 -0
  21. package/.genie/code/agents/code-quality.md +410 -0
  22. package/.genie/code/agents/commit-suggester.md +255 -0
  23. package/.genie/code/agents/commit.md +124 -0
  24. package/.genie/code/agents/consensus.md +204 -0
  25. package/.genie/code/agents/daily-standup.md +722 -0
  26. package/.genie/code/agents/docgen.md +48 -0
  27. package/.genie/code/agents/explore.md +79 -0
  28. package/.genie/code/agents/fix.md +100 -0
  29. package/.genie/code/agents/git/commit-advisory.md +219 -0
  30. package/.genie/code/agents/git/workflows/issue.md +244 -0
  31. package/.genie/code/agents/git/workflows/pr.md +179 -0
  32. package/.genie/code/agents/git/workflows/release.md +460 -0
  33. package/.genie/code/agents/git/workflows/report.md +342 -0
  34. package/.genie/code/agents/git.md +432 -0
  35. package/.genie/code/agents/implementor.md +161 -0
  36. package/.genie/code/agents/install.md +515 -0
  37. package/.genie/code/agents/issue-creator.md +344 -0
  38. package/.genie/code/agents/polish.md +116 -0
  39. package/.genie/code/agents/qa.md +653 -0
  40. package/.genie/code/agents/refactor.md +294 -0
  41. package/.genie/code/agents/release.md +1129 -0
  42. package/.genie/code/agents/roadmap.md +885 -0
  43. package/.genie/code/agents/tests.md +557 -0
  44. package/.genie/code/agents/tracer.md +50 -0
  45. package/.genie/code/agents/update/upstream-update.md +85 -0
  46. package/.genie/code/agents/update/versions/generic-update.md +305 -0
  47. package/.genie/code/agents/vibe.md +1317 -0
  48. package/.genie/code/spells/agent-configuration.md +58 -0
  49. package/.genie/code/spells/automated-rc-publishing.md +106 -0
  50. package/.genie/code/spells/branch-tracker-guidance.md +28 -0
  51. package/.genie/code/spells/debug.md +320 -0
  52. package/.genie/code/spells/emoji-naming-convention.md +303 -0
  53. package/.genie/code/spells/evidence-storage.md +26 -0
  54. package/.genie/code/spells/file-naming-rules.md +35 -0
  55. package/.genie/code/spells/forge-code-blueprints.md +195 -0
  56. package/.genie/code/spells/genie-integration.md +153 -0
  57. package/.genie/code/spells/publishing-protocol.md +61 -0
  58. package/.genie/code/spells/team-consultation-protocol.md +284 -0
  59. package/.genie/code/spells/tool-requirements.md +20 -0
  60. package/.genie/code/spells/triad-maintenance-protocol.md +154 -0
  61. package/.genie/code/teams/tech-council/council.md +328 -0
  62. package/.genie/code/teams/tech-council/jt.md +352 -0
  63. package/.genie/code/teams/tech-council/nayr.md +305 -0
  64. package/.genie/code/teams/tech-council/oettam.md +375 -0
  65. package/.genie/neurons/README.md +193 -0
  66. package/.genie/neurons/forge.md +106 -0
  67. package/.genie/neurons/genie.md +63 -0
  68. package/.genie/neurons/review.md +106 -0
  69. package/.genie/neurons/wish.md +104 -0
  70. package/.genie/product/README.md +20 -0
  71. package/.genie/product/cli-automation.md +359 -0
  72. package/.genie/product/environment.md +60 -0
  73. package/.genie/product/mission.md +60 -0
  74. package/.genie/product/roadmap.md +44 -0
  75. package/.genie/product/tech-stack.md +34 -0
  76. package/.genie/product/templates/context-template.md +218 -0
  77. package/.genie/product/templates/qa-done-report-template.md +68 -0
  78. package/.genie/product/templates/review-report-template.md +89 -0
  79. package/.genie/product/templates/wish-template.md +120 -0
  80. package/.genie/scripts/helpers/analyze-commit.js +195 -0
  81. package/.genie/scripts/helpers/bullet-counter.js +194 -0
  82. package/.genie/scripts/helpers/bullet-find.js +289 -0
  83. package/.genie/scripts/helpers/bullet-id.js +244 -0
  84. package/.genie/scripts/helpers/check-secrets.js +237 -0
  85. package/.genie/scripts/helpers/count-tokens.js +200 -0
  86. package/.genie/scripts/helpers/create-frontmatter.js +456 -0
  87. package/.genie/scripts/helpers/detect-markers.js +293 -0
  88. package/.genie/scripts/helpers/detect-todos.js +267 -0
  89. package/.genie/scripts/helpers/detect-unlabeled-blocks.js +135 -0
  90. package/.genie/scripts/helpers/embeddings.js +344 -0
  91. package/.genie/scripts/helpers/find-empty-sections.js +158 -0
  92. package/.genie/scripts/helpers/index.js +319 -0
  93. package/.genie/scripts/helpers/validate-frontmatter.js +578 -0
  94. package/.genie/scripts/helpers/validate-links.js +207 -0
  95. package/.genie/scripts/helpers/validate-paths.js +373 -0
  96. package/.genie/spells/README.md +9 -0
  97. package/.genie/spells/ace-protocol.md +118 -0
  98. package/.genie/spells/ask-one-at-a-time.md +175 -0
  99. package/.genie/spells/backup-analyzer.md +542 -0
  100. package/.genie/spells/blocker.md +12 -0
  101. package/.genie/spells/break-things-move-fast.md +56 -0
  102. package/.genie/spells/context-candidates.md +72 -0
  103. package/.genie/spells/context-critic.md +51 -0
  104. package/.genie/spells/defer-to-expertise.md +278 -0
  105. package/.genie/spells/delegate-dont-do.md +292 -0
  106. package/.genie/spells/error-investigation-protocol.md +328 -0
  107. package/.genie/spells/evidence-based-completion.md +273 -0
  108. package/.genie/spells/experiment.md +65 -0
  109. package/.genie/spells/file-creation-protocol.md +229 -0
  110. package/.genie/spells/forge-integration.md +281 -0
  111. package/.genie/spells/forge-orchestration.md +514 -0
  112. package/.genie/spells/gather-context.md +18 -0
  113. package/.genie/spells/global-health-check.md +34 -0
  114. package/.genie/spells/global-noop-roundtrip.md +25 -0
  115. package/.genie/spells/install-genie.md +1232 -0
  116. package/.genie/spells/install.md +82 -0
  117. package/.genie/spells/investigate-before-commit.md +112 -0
  118. package/.genie/spells/know-yourself.md +288 -0
  119. package/.genie/spells/learn.md +828 -0
  120. package/.genie/spells/mcp-diagnostic-protocol.md +246 -0
  121. package/.genie/spells/mcp-first.md +124 -0
  122. package/.genie/spells/multi-step-execution.md +67 -0
  123. package/.genie/spells/orchestration-boundary-protocol.md +256 -0
  124. package/.genie/spells/orchestrator-not-implementor.md +189 -0
  125. package/.genie/spells/prompt.md +746 -0
  126. package/.genie/spells/reflect.md +404 -0
  127. package/.genie/spells/routing-decision-matrix.md +368 -0
  128. package/.genie/spells/run-in-parallel.md +12 -0
  129. package/.genie/spells/session-state-updater-example.md +196 -0
  130. package/.genie/spells/session-state-updater.md +220 -0
  131. package/.genie/spells/track-long-running-tasks.md +133 -0
  132. package/.genie/spells/troubleshoot-infrastructure.md +176 -0
  133. package/.genie/spells/upgrade-genie.md +415 -0
  134. package/.genie/spells/url-presentation-protocol.md +301 -0
  135. package/.genie/spells/wish-initiation.md +158 -0
  136. package/.genie/spells/wish-issue-linkage.md +410 -0
  137. package/.genie/spells/wish-lifecycle.md +100 -0
  138. package/.genie/state/provider-status.json +3 -0
  139. package/.genie/state/version.json +16 -0
  140. package/AGENTS.md +422 -0
  141. package/CLAUDE.md +1 -0
  142. package/LICENSE +21 -0
  143. package/Makefile +235 -0
  144. package/README.md +323 -0
  145. package/bin/pglite-server.js +457 -0
  146. package/ecosystem.config.cjs +23 -0
  147. package/examples/multi-tenant-demo.js +104 -0
  148. package/package.json +47 -0
  149. package/src/detector.js +105 -0
  150. package/src/index.js +177 -0
  151. package/src/pool.js +320 -0
  152. package/src/ports.js +114 -0
  153. package/src/protocol.js +216 -0
  154. package/src/registry.js +134 -0
  155. package/src/router.js +289 -0
  156. package/src/server.js +265 -0
  157. package/tests/benchmarks/runner.js +489 -0
  158. package/tests/multi-tenant.test.js +201 -0
package/README.md ADDED
@@ -0,0 +1,323 @@
1
+ # pgserve
2
+
3
+ **Multi-tenant PostgreSQL router using PGlite** - Single port, auto-provisioning, zero config.
4
+
5
+ Perfect for multi-user apps, AI agents, and embedded databases.
6
+
7
+ ## ✨ Features
8
+
9
+ - 🎯 **Multi-Tenant** - Single port, multiple isolated databases (one per user/app)
10
+ - 🚀 **Auto-Provisioning** - Databases created on demand from connection string
11
+ - 🔌 **Single Endpoint** - `postgresql://localhost:8432/dbname` routes to correct PGlite instance
12
+ - ⚡ **High Performance** - MVCC, row-level locking, concurrent writes
13
+ - 🎛️ **Zero Configuration** - Auto-tuned for your hardware (CPU, RAM)
14
+ - 📦 **PostgreSQL Compatible** - Works with any PostgreSQL client (psql, Prisma, pg, etc.)
15
+ - 🛡️ **Data Isolation** - Each database = separate PGlite instance
16
+ - 💾 **Persistent** - Data survives restarts
17
+
18
+ ## 🎯 Use Cases
19
+
20
+ ### Perfect For
21
+
22
+ - 🤖 **AI Agents** - Each agent gets isolated database (sessions, memory, state)
23
+ - 👥 **Multi-User Apps** - One database per user, single endpoint
24
+ - 🏢 **SaaS Applications** - Tenant isolation without infrastructure complexity
25
+ - 🧪 **Development** - Local PostgreSQL without Docker
26
+ - 📱 **Desktop Apps** - Electron, Tauri with embedded multi-tenant DB
27
+
28
+ ### Real-World Examples
29
+
30
+ - **AI Agent Swarms**: 100+ agents, each with isolated database
31
+ - **Multi-Tenant SaaS**: Single endpoint, automatic tenant provisioning
32
+ - **Desktop Apps**: Embedded PostgreSQL with multi-user support
33
+
34
+ ## 🚀 Quick Start
35
+
36
+ ### Installation
37
+
38
+ ```bash
39
+ npm install pgserve
40
+ # or
41
+ pnpm add pgserve
42
+ ```
43
+
44
+ ### Multi-Tenant Mode (Recommended)
45
+
46
+ ```javascript
47
+ import { startMultiTenantServer } from 'pgserve';
48
+
49
+ // Start multi-tenant router on single port
50
+ const router = await startMultiTenantServer({
51
+ port: 8432, // Single port for all databases
52
+ baseDir: './data', // Base directory (creates ./data/dbname/ per DB)
53
+ autoProvision: true, // Auto-create databases (default: true)
54
+ maxInstances: 100, // Max concurrent databases
55
+ logLevel: 'info'
56
+ });
57
+
58
+ // Clients connect like normal PostgreSQL:
59
+ // postgresql://localhost:8432/user123 → ./data/user123/
60
+ // postgresql://localhost:8432/app456 → ./data/app456/
61
+ ```
62
+
63
+ ### Usage with PostgreSQL Clients
64
+
65
+ ```javascript
66
+ import pg from 'pg';
67
+
68
+ // Connect to database "user123" (auto-created)
69
+ const client1 = new pg.Client({
70
+ connectionString: 'postgresql://localhost:8432/user123'
71
+ });
72
+
73
+ await client1.connect();
74
+ await client1.query('CREATE TABLE users (id SERIAL, name TEXT)');
75
+ await client1.query("INSERT INTO users (name) VALUES ('Alice')");
76
+
77
+ // Connect to database "app456" (different isolated instance)
78
+ const client2 = new pg.Client({
79
+ connectionString: 'postgresql://localhost:8432/app456'
80
+ });
81
+
82
+ await client2.connect();
83
+ await client2.query('CREATE TABLE posts (id SERIAL, title TEXT)');
84
+
85
+ // Each database is completely isolated!
86
+ ```
87
+
88
+ ### With Prisma
89
+
90
+ ```javascript
91
+ // prisma/schema.prisma
92
+ datasource db {
93
+ provider = "postgresql"
94
+ url = env("DATABASE_URL")
95
+ }
96
+
97
+ // .env
98
+ DATABASE_URL="postgresql://localhost:8432/myapp"
99
+ ```
100
+
101
+ ```bash
102
+ # Auto-provisions "myapp" database
103
+ npx prisma migrate dev
104
+ ```
105
+
106
+ ## 📖 API Reference
107
+
108
+ ### `startMultiTenantServer(options)`
109
+
110
+ Start multi-tenant router server.
111
+
112
+ ```javascript
113
+ const router = await startMultiTenantServer({
114
+ port: 8432, // Port to listen on (default: 8432)
115
+ host: '127.0.0.1', // Host to bind (default: 127.0.0.1)
116
+ baseDir: './data', // Base data directory (default: './data')
117
+ autoProvision: true, // Auto-create databases (default: true)
118
+ maxInstances: 100, // Max concurrent databases (default: 100)
119
+ logLevel: 'info', // Log level: error, warn, info, debug (default: 'info')
120
+ inspect: false // Enable wire protocol debugging (default: false)
121
+ });
122
+
123
+ // Returns MultiTenantRouter instance
124
+ ```
125
+
126
+ ### Router Methods
127
+
128
+ ```javascript
129
+ // Get router stats
130
+ const stats = router.getStats();
131
+ // {
132
+ // port: 8432,
133
+ // activeConnections: 2,
134
+ // pool: {
135
+ // totalInstances: 3,
136
+ // maxInstances: 100,
137
+ // instances: [...]
138
+ // }
139
+ // }
140
+
141
+ // List all databases
142
+ const databases = router.listDatabases();
143
+ // [
144
+ // { dbName: 'user123', locked: false, queueLength: 0, ... },
145
+ // { dbName: 'app456', locked: true, queueLength: 1, ... }
146
+ // ]
147
+
148
+ // Stop router (closes all instances)
149
+ await router.stop();
150
+ ```
151
+
152
+ ## 🏗️ Architecture
153
+
154
+ ### Single Port, Multi-Tenant Routing
155
+
156
+ ```
157
+ Client 1: postgresql://localhost:8432/user123
158
+ Client 2: postgresql://localhost:8432/app456
159
+ Client 3: postgresql://localhost:8432/tenant789
160
+
161
+ ┌────────────────────────────────────────┐
162
+ │ Multi-Tenant Router (port 8432) │
163
+ │ - Parses connection database name │
164
+ │ - Routes to correct PGlite instance │
165
+ │ - Auto-provisions new databases │
166
+ └────────────────────────────────────────┘
167
+
168
+ ┌────────────────────────────────────────┐
169
+ │ Instance Pool │
170
+ │ ├─ user123 → PGlite('./data/user123') │
171
+ │ ├─ app456 → PGlite('./data/app456') │
172
+ │ └─ tenant789 → PGlite('./data/tenant789') │
173
+ └────────────────────────────────────────┘
174
+ ```
175
+
176
+ ### How It Works
177
+
178
+ 1. **Client connects**: `postgresql://localhost:8432/myapp`
179
+ 2. **Router parses** PostgreSQL startup message → extracts database name: `myapp`
180
+ 3. **Pool checks** for existing PGlite instance for `myapp`
181
+ 4. **Auto-provision** creates `./data/myapp/` if doesn't exist
182
+ 5. **Route connection** to PGlite instance
183
+ 6. **Client communicates** with isolated database
184
+
185
+ ### Connection Lifecycle
186
+
187
+ - **First connection to DB**: PGlite instance created, database initialized
188
+ - **Subsequent connections**: Reuses existing PGlite instance
189
+ - **Concurrent connections**: Queued (PGlite is single-connection per instance)
190
+ - **Connection closes**: Instance unlocked, ready for next connection
191
+
192
+ ## 📊 Performance
193
+
194
+ ### vs Multiple Port Approach
195
+
196
+ | Approach | Ports Used | Management | Scalability |
197
+ |----------|-----------|------------|-------------|
198
+ | **Multi-tenant** | 1 | Auto | ✅ Excellent (100+ DBs) |
199
+ | Multi-port | 1 per DB | Manual | ⚠️ Limited (port exhaustion) |
200
+
201
+ ### Benchmarks
202
+
203
+ - **DB creation**: ~50ms per database (lazy initialization)
204
+ - **Connection routing**: < 1ms overhead
205
+ - **Concurrent databases**: Tested with 100+ isolated instances
206
+ - **Memory**: ~10-30MB per PGlite instance (depends on data)
207
+
208
+ ## 🔧 CLI Usage
209
+
210
+ ### Install Globally
211
+
212
+ ```bash
213
+ npm install -g pgserve
214
+ ```
215
+
216
+ ### Commands
217
+
218
+ ```bash
219
+ # Start multi-tenant router
220
+ pgserve start --port 8432 --dir ./data
221
+
222
+ # Check router status
223
+ pgserve router-stats
224
+
225
+ # List all databases
226
+ pgserve list-databases
227
+
228
+ # Stop router
229
+ pgserve stop-router
230
+ ```
231
+
232
+ ## 🛠️ Advanced Usage
233
+
234
+ ### Custom Instance Pool
235
+
236
+ ```javascript
237
+ import { InstancePool } from 'pgserve';
238
+
239
+ const pool = new InstancePool({
240
+ baseDir: './databases',
241
+ maxInstances: 50,
242
+ autoProvision: true
243
+ });
244
+
245
+ // Get or create instance
246
+ const instance = await pool.getOrCreate('mydb');
247
+
248
+ // Access PGlite directly
249
+ const result = await instance.db.query('SELECT version()');
250
+ ```
251
+
252
+ ### Connection Queueing
253
+
254
+ PGlite is **single-connection** per instance. When multiple clients connect to the same database:
255
+
256
+ ```javascript
257
+ // Client 1 connects to "mydb" → locks instance
258
+ const client1 = new pg.Client({ database: 'mydb', ... });
259
+ await client1.connect(); // ✅ Connected
260
+
261
+ // Client 2 tries to connect to "mydb" → queued
262
+ const client2 = new pg.Client({ database: 'mydb', ... });
263
+ await client2.connect(); // ⏳ Waits for client1 to disconnect
264
+
265
+ // Client 1 disconnects
266
+ await client1.end();
267
+
268
+ // Client 2 auto-connects
269
+ // ✅ Connected
270
+ ```
271
+
272
+ Default timeout: **30 seconds**. Customize in `pool.acquire()`:
273
+
274
+ ```javascript
275
+ await pool.acquire('mydb', socket, timeout = 60000); // 60s timeout
276
+ ```
277
+
278
+ ## 🔐 Security Notes
279
+
280
+ - **No authentication**: PGlite doesn't support auth (embedded use case)
281
+ - **Bind to localhost**: Default `127.0.0.1` (local only)
282
+ - **Production**: Use proper PostgreSQL for external access
283
+
284
+ ## 📁 File Structure
285
+
286
+ ```
287
+ ./data/
288
+ ├─ user123/ (PGlite data for "user123" database)
289
+ │ ├─ base/
290
+ │ ├─ pg_wal/
291
+ │ └─ PG_VERSION
292
+ ├─ app456/ (PGlite data for "app456" database)
293
+ └─ tenant789/ (PGlite data for "tenant789" database)
294
+ ```
295
+
296
+ ## 🤝 Contributing
297
+
298
+ Contributions welcome! Please:
299
+
300
+ 1. Fork the repository
301
+ 2. Create a feature branch
302
+ 3. Add tests for new features
303
+ 4. Submit a pull request
304
+
305
+ ## 📄 License
306
+
307
+ MIT License - Copyright (c) 2025 Namastex Labs
308
+
309
+ ## 🙏 Credits
310
+
311
+ Built on top of:
312
+ - [@electric-sql/pglite](https://pglite.dev) - PostgreSQL WASM
313
+ - [@electric-sql/pglite-socket](https://www.npmjs.com/package/@electric-sql/pglite-socket) - Wire protocol server
314
+
315
+ ## 📧 Support
316
+
317
+ - **Issues**: [GitHub Issues](https://github.com/namastexlabs/pglite-embedded-server/issues)
318
+ - **Email**: labs@namastex.com
319
+ - **Website**: [namastex.com](https://namastex.com)
320
+
321
+ ---
322
+
323
+ **Made with ❤️ by [Namastex Labs](https://namastex.com)**