pgserve 1.1.3-rc.6 → 1.1.3-rc.7

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.
@@ -45,17 +45,14 @@ jobs:
45
45
  include:
46
46
  # Linux x64
47
47
  - platform: linux-x64
48
- pg_pkg: linux-x64
49
48
  output: pgserve-linux-x64
50
49
  os: ubuntu-latest
51
- # macOS ARM64 (Apple Silicon) - must build on macOS for native binaries
50
+ # macOS ARM64 (Apple Silicon)
52
51
  - platform: darwin-arm64
53
- pg_pkg: darwin-arm64
54
52
  output: pgserve-darwin-arm64
55
53
  os: macos-latest
56
54
  # Windows x64 - must build on Windows for --windows-icon
57
55
  - platform: windows-x64
58
- pg_pkg: windows-x64
59
56
  output: pgserve-windows-x64.exe
60
57
  os: windows-latest
61
58
 
@@ -73,18 +70,6 @@ jobs:
73
70
  - name: Install dependencies
74
71
  run: bun install
75
72
 
76
- # Bundle PostgreSQL binaries for standalone exe
77
- - name: Bundle PostgreSQL binaries
78
- run: |
79
- echo "Installing @embedded-postgres/${{ matrix.pg_pkg }}..."
80
- npm install @embedded-postgres/${{ matrix.pg_pkg }}
81
- mkdir -p embedded-postgres
82
- cp -r node_modules/@embedded-postgres/${{ matrix.pg_pkg }}/native/* embedded-postgres/
83
- echo "Bundled PostgreSQL binaries:"
84
- ls -la embedded-postgres/
85
- ls -la embedded-postgres/bin/ || true
86
- shell: bash
87
-
88
73
  # Windows: native build with custom icon
89
74
  - name: Build for Windows (with icon)
90
75
  if: matrix.platform == 'windows-x64'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pgserve",
3
- "version": "1.1.3-rc.6",
3
+ "version": "1.1.3-rc.7",
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/postgres.js CHANGED
@@ -13,6 +13,7 @@
13
13
  * - No locale dependency (works on any system)
14
14
  */
15
15
 
16
+ /* global fetch, Bun */
16
17
  import os from 'os';
17
18
  import path from 'path';
18
19
  import fs from 'fs';
@@ -45,71 +46,105 @@ function getBinaryCacheDir() {
45
46
  }
46
47
 
47
48
  /**
48
- * Check if bundled PostgreSQL binaries exist (standalone exe mode)
49
- * When compiled with `bun build --compile`, the embedded-postgres folder
50
- * should be bundled alongside the executable.
51
- * @returns {string|null} Path to bundled binaries or null if not found
52
- */
53
- function getBundledBinaryDir() {
54
- // Check for embedded-postgres folder relative to the module
55
- // This works when binaries are bundled during build
56
- const bundledDir = path.join(import.meta.dirname, '..', 'embedded-postgres');
57
- if (fs.existsSync(path.join(bundledDir, 'bin'))) {
58
- return bundledDir;
59
- }
60
- return null;
61
- }
62
-
63
- /**
64
- * Extract bundled PostgreSQL binaries to cache directory.
65
- * Bun-compiled binaries can read embedded files but cannot execute them directly.
66
- * We extract to ~/.pgserve/bin/{platform}/ for execution.
49
+ * Download and extract PostgreSQL binaries on first run.
50
+ * Downloads from npm registry (@embedded-postgres packages).
67
51
  *
68
- * @returns {Promise<string>} Path to extracted bin directory
52
+ * @returns {Promise<string>} Path to extracted directory
69
53
  */
70
- async function extractBundledBinaries() {
54
+ async function downloadPostgresBinaries() {
71
55
  const platform = os.platform();
72
56
  const cacheDir = getBinaryCacheDir();
73
57
  const cacheBinDir = path.join(cacheDir, 'bin');
74
58
  const initdbName = platform === 'win32' ? 'initdb.exe' : 'initdb';
75
59
  const postgresName = platform === 'win32' ? 'postgres.exe' : 'postgres';
76
60
 
77
- // Check if already extracted
61
+ // Check if already downloaded
78
62
  if (fs.existsSync(path.join(cacheBinDir, initdbName)) &&
79
63
  fs.existsSync(path.join(cacheBinDir, postgresName))) {
80
64
  return cacheDir;
81
65
  }
82
66
 
83
- // Get bundled directory
84
- const bundledDir = getBundledBinaryDir();
85
- if (!bundledDir) {
86
- return null;
67
+ const platformKey = getPlatformKey();
68
+ const pkgName = `@embedded-postgres/${platformKey}`;
69
+ const pkgVersion = '17.7.0-beta.15';
70
+
71
+ console.log(`[pgserve] PostgreSQL binaries not found.`);
72
+ console.log(`[pgserve] Downloading ${pkgName}@${pkgVersion}...`);
73
+
74
+ // Get tarball URL from npm registry
75
+ const registryUrl = `https://registry.npmjs.org/${pkgName}`;
76
+ const registryRes = await fetch(registryUrl);
77
+ if (!registryRes.ok) {
78
+ throw new Error(`Failed to fetch package info: ${registryRes.status}`);
87
79
  }
80
+ const pkgInfo = await registryRes.json();
81
+ const tarballUrl = pkgInfo.versions[pkgVersion]?.dist?.tarball;
88
82
 
89
- console.log('[pgserve] Extracting PostgreSQL binaries...');
83
+ if (!tarballUrl) {
84
+ throw new Error(`Version ${pkgVersion} not found for ${pkgName}`);
85
+ }
86
+
87
+ // Download tarball
88
+ console.log(`[pgserve] Downloading from npm registry...`);
89
+ const tarballRes = await fetch(tarballUrl);
90
+ if (!tarballRes.ok) {
91
+ throw new Error(`Failed to download tarball: ${tarballRes.status}`);
92
+ }
93
+
94
+ const tarballBuffer = await tarballRes.arrayBuffer();
95
+ const tarballSize = (tarballBuffer.byteLength / 1024 / 1024).toFixed(1);
96
+ console.log(`[pgserve] Downloaded ${tarballSize} MB`);
90
97
 
91
- // Create cache directory
98
+ // Create temp file for tarball
99
+ const tempDir = path.join(os.tmpdir(), `pgserve-download-${Date.now()}`);
100
+ fs.mkdirSync(tempDir, { recursive: true });
101
+ const tarballPath = path.join(tempDir, 'package.tgz');
102
+ fs.writeFileSync(tarballPath, Buffer.from(tarballBuffer));
103
+
104
+ // Extract tarball using tar (available on all platforms via bun/node)
105
+ console.log(`[pgserve] Extracting binaries...`);
92
106
  fs.mkdirSync(cacheDir, { recursive: true });
93
107
 
94
- // Copy bundled binaries to cache
95
- // Use recursive copy to get bin/, lib/, share/ directories
96
- await copyRecursive(bundledDir, cacheDir);
108
+ // Use Bun.spawn for extraction
109
+ const extractProc = Bun.spawn(['tar', '-xzf', tarballPath, '-C', tempDir], {
110
+ stdout: 'pipe',
111
+ stderr: 'pipe'
112
+ });
113
+ await extractProc.exited;
114
+
115
+ // Copy native/* to cache dir
116
+ const nativeDir = path.join(tempDir, 'package', 'native');
117
+ if (!fs.existsSync(nativeDir)) {
118
+ throw new Error('Extracted package does not contain native/ directory');
119
+ }
120
+
121
+ // Copy files recursively
122
+ await copyDirRecursive(nativeDir, cacheDir);
97
123
 
98
124
  // Make executables executable (Unix only)
99
125
  if (platform !== 'win32') {
100
126
  const binDir = path.join(cacheDir, 'bin');
101
- const files = fs.readdirSync(binDir);
102
- for (const file of files) {
103
- const filePath = path.join(binDir, file);
104
- try {
105
- fs.chmodSync(filePath, 0o755);
106
- } catch {
107
- // Ignore permission errors for non-executables
127
+ if (fs.existsSync(binDir)) {
128
+ const files = fs.readdirSync(binDir);
129
+ for (const file of files) {
130
+ const filePath = path.join(binDir, file);
131
+ try {
132
+ fs.chmodSync(filePath, 0o755);
133
+ } catch {
134
+ // Ignore
135
+ }
108
136
  }
109
137
  }
110
138
  }
111
139
 
112
- console.log(`[pgserve] Binaries extracted to ${cacheDir}`);
140
+ // Cleanup temp
141
+ try {
142
+ fs.rmSync(tempDir, { recursive: true, force: true });
143
+ } catch {
144
+ // Ignore cleanup errors
145
+ }
146
+
147
+ console.log(`[pgserve] PostgreSQL binaries installed to ${cacheDir}`);
113
148
  return cacheDir;
114
149
  }
115
150
 
@@ -118,7 +153,7 @@ async function extractBundledBinaries() {
118
153
  * @param {string} src - Source directory
119
154
  * @param {string} dest - Destination directory
120
155
  */
121
- async function copyRecursive(src, dest) {
156
+ async function copyDirRecursive(src, dest) {
122
157
  const entries = fs.readdirSync(src, { withFileTypes: true });
123
158
 
124
159
  for (const entry of entries) {
@@ -127,11 +162,9 @@ async function copyRecursive(src, dest) {
127
162
 
128
163
  if (entry.isDirectory()) {
129
164
  fs.mkdirSync(destPath, { recursive: true });
130
- await copyRecursive(srcPath, destPath);
165
+ await copyDirRecursive(srcPath, destPath);
131
166
  } else {
132
- // Read and write file (works with Bun's virtual filesystem)
133
- const content = fs.readFileSync(srcPath);
134
- fs.writeFileSync(destPath, content);
167
+ fs.copyFileSync(srcPath, destPath);
135
168
  }
136
169
  }
137
170
  }
@@ -233,22 +266,20 @@ async function getBinaryPaths() {
233
266
  return { initdb: cachedInitdb, postgres: cachedPostgres, binDir: cacheBinDir, libDir };
234
267
  }
235
268
 
236
- // Priority 2: Check for bundled binaries and extract if found (standalone exe mode)
237
- const bundledDir = getBundledBinaryDir();
238
- if (bundledDir) {
239
- const extractedDir = await extractBundledBinaries();
240
- if (extractedDir) {
241
- const extractedBinDir = path.join(extractedDir, 'bin');
242
- const extractedInitdb = path.join(extractedBinDir, 'initdb' + exeSuffix);
243
- const extractedPostgres = path.join(extractedBinDir, 'postgres' + exeSuffix);
244
-
245
- if (fs.existsSync(extractedInitdb) && fs.existsSync(extractedPostgres)) {
246
- const libDir = path.join(extractedDir, 'lib');
247
- if ((platform === 'linux' || platform === 'darwin') && fs.existsSync(libDir)) {
248
- ensureLibrarySymlinks(libDir, platform);
249
- }
250
- return { initdb: extractedInitdb, postgres: extractedPostgres, binDir: extractedBinDir, libDir };
269
+ // Priority 2: Download binaries if not found (standalone exe mode)
270
+ // This downloads from npm registry on first run
271
+ const downloadedDir = await downloadPostgresBinaries();
272
+ if (downloadedDir) {
273
+ const downloadedBinDir = path.join(downloadedDir, 'bin');
274
+ const downloadedInitdb = path.join(downloadedBinDir, 'initdb' + exeSuffix);
275
+ const downloadedPostgres = path.join(downloadedBinDir, 'postgres' + exeSuffix);
276
+
277
+ if (fs.existsSync(downloadedInitdb) && fs.existsSync(downloadedPostgres)) {
278
+ const libDir = path.join(downloadedDir, 'lib');
279
+ if ((platform === 'linux' || platform === 'darwin') && fs.existsSync(libDir)) {
280
+ ensureLibrarySymlinks(libDir, platform);
251
281
  }
282
+ return { initdb: downloadedInitdb, postgres: downloadedPostgres, binDir: downloadedBinDir, libDir };
252
283
  }
253
284
  }
254
285