pgserve 1.0.4 → 1.0.6

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/Makefile CHANGED
@@ -111,10 +111,13 @@ check-npm: ## Check npm authentication
111
111
  @echo "$(CYAN)🔍 Checking npm authentication...$(RESET)"
112
112
  @if ! npm whoami >/dev/null 2>&1; then \
113
113
  echo "$(RED)❌ Not logged in to npm!$(RESET)"; \
114
- echo "$(YELLOW)Run: npm login$(RESET)"; \
114
+ echo "$(YELLOW)Run: npm login --auth-type=legacy$(RESET)"; \
115
115
  exit 1; \
116
116
  fi
117
117
  @echo "$(GREEN)✅ Logged in as: $$(npm whoami)$(RESET)"
118
+ @if [ -z "$$NPM_TOKEN" ] && ! grep -q "_authToken" ~/.npmrc 2>/dev/null; then \
119
+ echo "$(YELLOW)⚠️ Consider using NPM_TOKEN or ~/.npmrc for non-interactive publish$(RESET)"; \
120
+ fi
118
121
 
119
122
  check-version: ## Check if version tag exists
120
123
  @echo "$(CYAN)🔍 Checking version $(VERSION)...$(RESET)"
@@ -178,7 +181,7 @@ publish: check-git check-npm check-files ## 🚀 Publish to npm (auto-bumps vers
178
181
  fi; \
179
182
  echo ""; \
180
183
  echo "$(CYAN)📦 Publishing to npm...$(RESET)"; \
181
- npm publish --access public; \
184
+ npm publish --access public || { echo "$(RED)❌ npm publish failed! Run manually: npm publish --access public$(RESET)"; exit 1; }; \
182
185
  echo "$(GREEN)✅ Published to npm!$(RESET)"; \
183
186
  echo ""; \
184
187
  if command -v gh >/dev/null 2>&1; then \
package/README.md CHANGED
@@ -99,7 +99,7 @@ npm install pgserve
99
99
  pgserve [options]
100
100
 
101
101
  Options:
102
- --port <number> PostgreSQL port (default: 5432)
102
+ --port <number> PostgreSQL port (default: 8432)
103
103
  --data <path> Data directory for persistence (default: in-memory)
104
104
  --host <host> Host to bind to (default: 127.0.0.1)
105
105
  --log <level> Log level: error, warn, info, debug (default: info)
@@ -139,7 +139,7 @@ pgserve --sync-to "postgresql://user:pass@db.example.com:5432/prod"
139
139
  import { startMultiTenantServer } from 'pgserve';
140
140
 
141
141
  const server = await startMultiTenantServer({
142
- port: 5432,
142
+ port: 8432,
143
143
  host: '127.0.0.1',
144
144
  baseDir: null, // null = memory mode
145
145
  logLevel: 'info',
@@ -42,7 +42,7 @@ USAGE:
42
42
  pgserve [options]
43
43
 
44
44
  OPTIONS:
45
- --port <number> PostgreSQL port (default: 5432)
45
+ --port <number> PostgreSQL port (default: 8432)
46
46
  --data <path> Data directory for persistence (default: in-memory)
47
47
  --host <host> Host to bind to (default: 127.0.0.1)
48
48
  --log <level> Log level: error, warn, info, debug (default: info)
@@ -95,7 +95,7 @@ function parseArgs() {
95
95
  const cpuCount = os.cpus().length;
96
96
 
97
97
  const options = {
98
- port: 5432,
98
+ port: 8432,
99
99
  host: '127.0.0.1',
100
100
  dataDir: null, // null = memory mode
101
101
  logLevel: 'info',
@@ -179,10 +179,13 @@ async function main() {
179
179
  const options = parseArgs();
180
180
  const memoryMode = !options.dataDir;
181
181
 
182
- console.log(`
182
+ // Only print header if not a cluster worker (workers get PGSERVE_WORKER env)
183
+ if (!process.env.PGSERVE_WORKER) {
184
+ console.log(`
183
185
  pgserve - Embedded PostgreSQL Server
184
186
  =====================================
185
187
  `);
188
+ }
186
189
 
187
190
  try {
188
191
  let server;
@@ -254,16 +257,18 @@ Press Ctrl+C to stop
254
257
  `);
255
258
  }
256
259
 
257
- // Graceful shutdown
258
- const shutdown = async () => {
259
- console.log('\nShutting down...');
260
- await server.stop();
261
- console.log('Server stopped.');
262
- process.exit(0);
263
- };
260
+ // Graceful shutdown (only for primary/single-process, workers handle via IPC)
261
+ if (!process.env.PGSERVE_WORKER) {
262
+ const shutdown = async () => {
263
+ console.log('\nShutting down...');
264
+ await server.stop();
265
+ console.log('Server stopped.');
266
+ process.exit(0);
267
+ };
264
268
 
265
- process.on('SIGINT', shutdown);
266
- process.on('SIGTERM', shutdown);
269
+ process.on('SIGINT', shutdown);
270
+ process.on('SIGTERM', shutdown);
271
+ }
267
272
 
268
273
  // Keep process alive
269
274
  await new Promise(() => {});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgserve",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Embedded PostgreSQL server with true concurrent connections - zero config, auto-provision databases",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/cluster.js CHANGED
@@ -25,7 +25,7 @@ import { EventEmitter } from 'events';
25
25
  class ClusterRouter extends EventEmitter {
26
26
  constructor(options = {}) {
27
27
  super();
28
- this.port = options.port || 5432;
28
+ this.port = options.port || 8432;
29
29
  this.host = options.host || '127.0.0.1';
30
30
  this.pgSocketPath = options.pgSocketPath; // From PRIMARY
31
31
  this.pgPort = options.pgPort;
@@ -74,6 +74,8 @@ class ClusterRouter extends EventEmitter {
74
74
  }
75
75
 
76
76
  this.adminClient = new pg.Client(connectionConfig);
77
+ // Suppress errors during shutdown (PostgreSQL terminating connections)
78
+ this.adminClient.on('error', () => {});
77
79
  await this.adminClient.connect();
78
80
  }
79
81
 
@@ -178,7 +180,11 @@ class ClusterRouter extends EventEmitter {
178
180
  this.connections.clear();
179
181
 
180
182
  if (this.adminClient) {
181
- await this.adminClient.end();
183
+ try {
184
+ await this.adminClient.end();
185
+ } catch {
186
+ // Ignore - connection may already be terminated
187
+ }
182
188
  }
183
189
 
184
190
  if (this.server) {
@@ -192,7 +198,7 @@ class ClusterRouter extends EventEmitter {
192
198
  */
193
199
  export async function startClusterServer(options = {}) {
194
200
  const numWorkers = options.workers || os.cpus().length;
195
- const port = options.port || 5432;
201
+ const port = options.port || 8432;
196
202
  const host = options.host || '127.0.0.1';
197
203
  const pgPort = options.pgPort || (port + 1000);
198
204
 
@@ -231,11 +237,18 @@ export async function startClusterServer(options = {}) {
231
237
  workers.set(worker.id, worker);
232
238
  }
233
239
 
234
- // Restart dead workers
240
+ // Track shutdown state to prevent worker restart during shutdown
241
+ let shuttingDown = false;
242
+
243
+ // Restart dead workers (unless shutting down)
235
244
  cluster.on('exit', (worker, code, signal) => {
236
- console.log(`[pgserve] Worker ${worker.id} died (${signal || code}), restarting...`);
237
245
  workers.delete(worker.id);
238
246
 
247
+ if (shuttingDown) {
248
+ return; // Don't restart during shutdown
249
+ }
250
+
251
+ console.log(`[pgserve] Worker ${worker.id} died (${signal || code}), restarting...`);
239
252
  const newWorker = cluster.fork({
240
253
  PGSERVE_WORKER: 'true',
241
254
  PGSERVE_PORT: String(port),
@@ -270,6 +283,7 @@ export async function startClusterServer(options = {}) {
270
283
  pgSocketPath,
271
284
  stop: async () => {
272
285
  console.log('[pgserve] Stopping cluster...');
286
+ shuttingDown = true; // Prevent worker restart during shutdown
273
287
  for (const worker of workers.values()) {
274
288
  worker.send({ type: 'shutdown' });
275
289
  }
@@ -292,7 +306,7 @@ export async function startClusterServer(options = {}) {
292
306
  } else {
293
307
  // WORKER: Only run TCP routing, connect to PRIMARY's PostgreSQL
294
308
  const router = new ClusterRouter({
295
- port: parseInt(process.env.PGSERVE_PORT) || 5432,
309
+ port: parseInt(process.env.PGSERVE_PORT) || 8432,
296
310
  host: process.env.PGSERVE_HOST || '127.0.0.1',
297
311
  pgSocketPath: process.env.PGSERVE_PG_SOCKET || null,
298
312
  pgPort: parseInt(process.env.PGSERVE_PG_PORT) || 6432,
package/src/dashboard.js CHANGED
@@ -56,7 +56,7 @@ export class Dashboard {
56
56
  */
57
57
  showHeader(config = {}) {
58
58
  const mode = config.memoryMode ? 'In-memory' : 'Persistent';
59
- const port = config.port || 5432;
59
+ const port = config.port || 8432;
60
60
  const host = config.host || '127.0.0.1';
61
61
  const syncTo = config.syncTo ? ` → ${this._maskUrl(config.syncTo)}` : '';
62
62
 
@@ -169,7 +169,7 @@ export class Dashboard {
169
169
  * Show final ready message
170
170
  */
171
171
  showReady(config = {}) {
172
- const port = config.port || 5432;
172
+ const port = config.port || 8432;
173
173
  const host = config.host || '127.0.0.1';
174
174
 
175
175
  console.log('');
package/src/router.js CHANGED
@@ -27,7 +27,7 @@ import pino from 'pino';
27
27
  export class MultiTenantRouter extends EventEmitter {
28
28
  constructor(options = {}) {
29
29
  super();
30
- this.port = options.port || 5432;
30
+ this.port = options.port || 8432;
31
31
  this.host = options.host || '127.0.0.1';
32
32
  this.baseDir = options.baseDir || null; // null = memory mode
33
33
  this.memoryMode = !options.baseDir;