postgres-memory-server 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Spin up a disposable **real** PostgreSQL or ParadeDB instance in tests with a tiny API inspired by `mongodb-memory-server` and `redisjson-memory-server`.
4
4
 
5
- This package does **not** emulate Postgres. It starts an actual database container and gives you a normal Postgres connection string.
5
+ This package does **not** emulate Postgres. It starts an actual PostgreSQL process using native binaries **no Docker required**.
6
6
 
7
7
  ## Why this exists
8
8
 
@@ -11,29 +11,34 @@ For Postgres extension-heavy workloads, especially ParadeDB + `pgvector`, a real
11
11
  - no shared local database contamination
12
12
  - deterministic integration tests
13
13
  - realistic extension behavior
14
- - straightforward CI/CD setup
14
+ - straightforward CI/CD setup — no Docker daemon needed
15
15
  - one API for plain Postgres and ParadeDB
16
16
 
17
17
  ## Features
18
18
 
19
- - Start a disposable Postgres container with `create()`
19
+ - Start a disposable Postgres instance with `create()` — no Docker
20
+ - PostgreSQL binaries bundled via [`embedded-postgres`](https://github.com/leinelissen/embedded-postgres)
21
+ - ParadeDB `pg_search` and `pgvector` extensions auto-downloaded from official releases
20
22
  - Get a ready-to-use connection string with `getUri()`
21
- - Use the same API for plain Postgres or ParadeDB presets
22
23
  - Run SQL strings, SQL files, or a migrations directory
23
24
  - Snapshot and restore database state between tests
25
+ - Extension binaries cached in `~/.cache/postgres-memory-server/`
24
26
  - CLI for local scripts and debugging
25
27
 
26
28
  ## Requirements
27
29
 
28
30
  - Node.js 20+
29
- - Docker available to the current user
31
+
32
+ That's it. No Docker, no system Postgres installation needed.
30
33
 
31
34
  ## Install
32
35
 
33
36
  ```bash
34
- npm install -D postgres-memory-server pg
37
+ npm install -D postgres-memory-server
35
38
  ```
36
39
 
40
+ The `pg` client library is included as a dependency.
41
+
37
42
  ## Quick start
38
43
 
39
44
  ```ts
@@ -69,28 +74,52 @@ await db.runSql(`
69
74
  await db.stop();
70
75
  ```
71
76
 
72
- By default, the ParadeDB preset uses the official ParadeDB image and runs:
77
+ By default, the ParadeDB preset automatically downloads and installs the extensions, then runs:
73
78
 
74
79
  ```sql
75
80
  CREATE EXTENSION IF NOT EXISTS pg_search;
76
81
  CREATE EXTENSION IF NOT EXISTS vector;
77
82
  ```
78
83
 
79
- The default image is pinned to `paradedb/paradedb:0.22.3-pg17` so local runs and CI stay reproducible.
84
+ Extension binaries are downloaded once and cached in `~/.cache/postgres-memory-server/`.
80
85
 
81
- If you want to test against a different Postgres or ParadeDB version, pass `version`. The package resolves the correct image repository for the selected preset.
86
+ - `pg_search` is downloaded from [ParadeDB GitHub releases](https://github.com/paradedb/paradedb/releases)
87
+ - `pgvector` is downloaded from [Homebrew bottles](https://formulae.brew.sh/formula/pgvector) (covers macOS + Linux)
82
88
 
83
- ```ts
84
- const postgres16 = await PostgresMemoryServer.createPostgres({
85
- version: "16",
86
- });
89
+ ## How it works
87
90
 
88
- const paradeDbPg16 = await PostgresMemoryServer.createParadeDb({
89
- version: "0.22.3-pg16",
90
- });
91
+ Instead of Docker containers, this package uses:
92
+
93
+ 1. **[embedded-postgres](https://github.com/leinelissen/embedded-postgres)** — bundles PostgreSQL binaries as npm packages (~10MB). The PostgreSQL version is determined by the installed `embedded-postgres` npm package version (e.g., `embedded-postgres@18.x` = PostgreSQL 18).
94
+
95
+ 2. **Native extension installation** — for the ParadeDB preset, `pg_search` and `pgvector` extension binaries are downloaded from their official release channels, extracted, and installed into the embedded PostgreSQL directory.
96
+
97
+ 3. **Template database snapshots** — `snapshot()` and `restore()` use PostgreSQL's native `CREATE DATABASE ... TEMPLATE` for fast, zero-copy test isolation.
98
+
99
+ ### PostgreSQL version
100
+
101
+ The PostgreSQL version is tied to the `embedded-postgres` npm package version. To use a specific PG version:
102
+
103
+ ```bash
104
+ # PG 18 (default with latest embedded-postgres)
105
+ npm install -D embedded-postgres
106
+
107
+ # PG 17
108
+ npm install -D embedded-postgres@17.9.0-beta.16
109
+
110
+ # PG 16
111
+ npm install -D embedded-postgres@16.8.0-beta.16
91
112
  ```
92
113
 
93
- Use `image` when you want an exact override, such as a private registry, a custom build, or a nonstandard tag. When both `version` and `image` are provided, `image` wins.
114
+ ### Platform support
115
+
116
+ | Platform | Postgres | ParadeDB pg_search | pgvector |
117
+ |----------|----------|--------------------|----------|
118
+ | macOS arm64 (Apple Silicon) | Yes | Yes | Yes |
119
+ | macOS x64 (Intel) | Yes | No | Yes |
120
+ | Linux x64 | Yes | Yes | Yes |
121
+ | Linux arm64 | Yes | Yes | Yes |
122
+ | Windows x64 | Yes | No | No |
94
123
 
95
124
  ## API
96
125
 
@@ -100,7 +129,6 @@ Create a disposable Postgres instance.
100
129
 
101
130
  ```ts
102
131
  const db = await PostgresMemoryServer.create({
103
- version: "17",
104
132
  database: "testdb",
105
133
  username: "testuser",
106
134
  password: "testpassword",
@@ -112,22 +140,28 @@ const db = await PostgresMemoryServer.create({
112
140
  Convenience alias for the plain Postgres preset.
113
141
 
114
142
  ```ts
115
- const db = await PostgresMemoryServer.createPostgres({
116
- version: "15",
117
- });
143
+ const db = await PostgresMemoryServer.createPostgres();
118
144
  ```
119
145
 
120
146
  ### `PostgresMemoryServer.createParadeDb(options?)`
121
147
 
122
- Starts a ParadeDB container and creates the default extensions.
148
+ Starts a Postgres instance with ParadeDB extensions (pg_search + pgvector).
123
149
 
124
150
  ```ts
125
- const db = await PostgresMemoryServer.createParadeDb({
126
- version: "0.22.3-pg17",
127
- });
151
+ const db = await PostgresMemoryServer.createParadeDb();
128
152
  ```
129
153
 
130
- The preset still controls the default extensions. Overriding `version` or `image` only changes which container tag is started.
154
+ ### Options
155
+
156
+ | Option | Type | Default | Description |
157
+ |--------|------|---------|-------------|
158
+ | `preset` | `"postgres" \| "paradedb"` | `"postgres"` | Controls default extensions |
159
+ | `version` | `string` | — | ParadeDB extension version (e.g., `"0.22.5"`) |
160
+ | `database` | `string` | `"testdb"` | Database name |
161
+ | `username` | `string` | `"testuser"` | Username |
162
+ | `password` | `string` | `"testpassword"` | Password |
163
+ | `extensions` | `string[]` | preset default | Extensions to create |
164
+ | `initSql` | `string[]` | `[]` | SQL statements to run after setup |
131
165
 
132
166
  ### `createJestGlobalSetup(options?)`
133
167
 
@@ -139,20 +173,22 @@ Stops the process started by `createJestGlobalSetup()`.
139
173
 
140
174
  ### Instance methods
141
175
 
142
- - `getUri()`
143
- - `getHost()`
144
- - `getPort()`
176
+ - `getUri()` — connection string (`postgres://...`)
177
+ - `getHost()` — always `localhost`
178
+ - `getPort()` — randomly assigned free port
145
179
  - `getDatabase()`
146
180
  - `getUsername()`
147
181
  - `getPassword()`
148
- - `getConnectionOptions()`
149
- - `query(text, params?)`
150
- - `runSql(sql)`
151
- - `runSqlFile(filePath)`
152
- - `runMigrationsDir(dirPath)`
153
- - `snapshot()`
154
- - `restore()`
155
- - `stop()`
182
+ - `getConnectionOptions()` — `{ host, port, database, user, password }`
183
+ - `getImage()` — descriptive label (e.g., `"postgres:18"`)
184
+ - `query(text, params?)` — execute a query and return rows
185
+ - `withClient(callback)` — direct access to a `pg.Client`
186
+ - `runSql(sql)` — execute one or more SQL statements
187
+ - `runSqlFile(filePath)` — execute SQL from a file
188
+ - `runMigrationsDir(dirPath)` — run `.sql` files in lexicographic order
189
+ - `snapshot()` — create a restore point
190
+ - `restore()` — restore to last snapshot
191
+ - `stop()` — shut down the PostgreSQL process
156
192
 
157
193
  ## Snapshots
158
194
 
@@ -176,7 +212,7 @@ const result = await db.query<{ count: string }>(
176
212
  console.log(result.rows[0]?.count); // 1
177
213
  ```
178
214
 
179
- Use a non-system database name when you plan to use snapshots. The package defaults to `testdb` for that reason.
215
+ Snapshots use PostgreSQL template databases under the hood. Use a non-system database name (the default `testdb` works).
180
216
 
181
217
  ## Running SQL files or migrations
182
218
 
@@ -193,34 +229,24 @@ Migration files are run in lexicographic order.
193
229
  npx postgres-memory-server --preset paradedb
194
230
  ```
195
231
 
196
- To test a specific version from the CLI, pass `--version`:
197
-
198
- ```bash
199
- npx postgres-memory-server --preset postgres --version 16
200
- npx postgres-memory-server --preset paradedb --version 0.22.3-pg16
201
- ```
202
-
203
- If you need an exact image reference instead, `--image` still works and takes precedence over `--version`.
204
-
205
232
  Example output:
206
233
 
207
234
  ```bash
208
- POSTGRES_MEMORY_SERVER_URI=postgres://testuser:testpassword@127.0.0.1:54329/testdb
209
- POSTGRES_MEMORY_SERVER_HOST=127.0.0.1
235
+ POSTGRES_MEMORY_SERVER_URI=postgres://testuser:testpassword@localhost:54329/testdb
236
+ POSTGRES_MEMORY_SERVER_HOST=localhost
210
237
  POSTGRES_MEMORY_SERVER_PORT=54329
211
238
  POSTGRES_MEMORY_SERVER_DATABASE=testdb
212
239
  POSTGRES_MEMORY_SERVER_USERNAME=testuser
213
240
  POSTGRES_MEMORY_SERVER_PASSWORD=testpassword
214
- ```
215
241
 
216
- The CLI keeps the container alive until you exit with `Ctrl+C`.
242
+ Press Ctrl+C to stop the server.
243
+ ```
217
244
 
218
245
  ### CLI flags
219
246
 
220
247
  ```bash
221
248
  --preset postgres|paradedb
222
249
  --version <tag>
223
- --image <image>
224
250
  --database <name>
225
251
  --username <name>
226
252
  --password <password>
@@ -229,15 +255,6 @@ The CLI keeps the container alive until you exit with `Ctrl+C`.
229
255
  --json
230
256
  ```
231
257
 
232
- ## Test scripts
233
-
234
- ```bash
235
- npm run test:postgres
236
- npm run test:paradedb
237
- ```
238
-
239
- These scripts are useful locally and are also what the GitHub Actions workflow uses.
240
-
241
258
  ## Jest global setup
242
259
 
243
260
  ```ts
@@ -246,7 +263,6 @@ import { createJestGlobalSetup } from "postgres-memory-server";
246
263
 
247
264
  export default createJestGlobalSetup({
248
265
  preset: "paradedb",
249
- version: "0.22.3-pg16",
250
266
  });
251
267
  ```
252
268
 
@@ -310,29 +326,38 @@ describe("db", () => {
310
326
  });
311
327
  ```
312
328
 
313
- ## Caveats
329
+ ## Migrating from v0.1.0 (Docker-based)
330
+
331
+ v0.2.0 replaces Docker containers with native binaries. Key changes:
314
332
 
315
- - This package depends on Docker. It is intentionally built around a real database, not an emulator.
316
- - Snapshot and restore require no active client connections during those operations.
317
- - The ParadeDB preset creates extensions in the target database, but you are still responsible for your schema, indexes, and test data.
318
- - The package is ESM-only in this starter repo. If you need CJS, add a second build target.
333
+ | v0.1.0 | v0.2.0 |
334
+ |--------|--------|
335
+ | Requires Docker daemon | No Docker needed |
336
+ | `@testcontainers/postgresql` | `embedded-postgres` |
337
+ | PG version via `version` option | PG version via `embedded-postgres` npm version |
338
+ | `image` option for Docker images | `image` option deprecated (ignored) |
339
+ | Container snapshots | Template database snapshots |
319
340
 
320
- ## Publishing checklist
341
+ **Breaking changes:**
342
+ - The `image` option is deprecated and ignored. Remove it from your code.
343
+ - The `version` option for the `postgres` preset is ignored — install the desired `embedded-postgres@<version>` package instead.
344
+ - The `version` option for the `paradedb` preset now refers to the ParadeDB extension version (e.g., `"0.22.5"`), not the Docker image tag.
321
345
 
322
- Before publishing:
346
+ **No changes needed if** you only used `create()`, `createPostgres()`, or `createParadeDb()` with just `database`, `username`, `password`, or `extensions` options.
347
+
348
+ ## Caveats
323
349
 
324
- 1. update the package name in `package.json` if you plan to publish under a scope
325
- 2. update repository URLs in `package.json`
326
- 3. run `npm install`
327
- 4. run `npm test`
328
- 5. publish with `npm publish --access public`
350
+ - The PostgreSQL version is determined by the installed `embedded-postgres` npm package, not by a runtime option.
351
+ - ParadeDB `pg_search` requires macOS arm64 or Linux. Intel Macs and Windows are not supported for ParadeDB.
352
+ - Snapshot and restore terminate other connections to the database during the operation.
353
+ - The package is ESM-only.
329
354
 
330
- ## Roadmap
355
+ ## Test scripts
331
356
 
332
- - reusable container mode
333
- - worker-isolated databases
334
- - Docker Compose / Podman engine adapters
335
- - optional non-Docker backend
357
+ ```bash
358
+ npm run test:postgres
359
+ npm run test:paradedb
360
+ ```
336
361
 
337
362
  ## License
338
363