@di-framework/pglite-component 6.0.14 → 6.0.16

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
@@ -1,6 +1,6 @@
1
1
  # di-framework:pglite — embedded PostgreSQL over WIT
2
2
 
3
- The provider bundles the PGlite PostgreSQL 17.5 engine into a WebAssembly
3
+ The provider bundles a PostgreSQL 17.11 engine, built for WASI, into a WebAssembly
4
4
  component. SQL calls cross WIT and WebAssembly memory. There is no TCP listener,
5
5
  network client, native sidecar, or separate database service.
6
6
 
@@ -59,12 +59,56 @@ is cached under `target/engine`. Containers are build tools only; deployment
59
59
  runs the resulting `.wasm` directly. For a remote Podman daemon, set the task's
60
60
  `DOCKER_CONTEXT=podman`.
61
61
 
62
+ ### Engine source
63
+
64
+ The engine is upstream PostgreSQL `REL_17_11` with ElectricSQL's PGlite WASI
65
+ changes replayed onto it. Electric maintains no WASI branch past 17.5 (its newer
66
+ branches are Emscripten-only), so the 17.5 WASI changes are carried as
67
+ [`engine/patches/postgresql-17.11-wasi.patch`](engine/patches/README.md)
68
+ (PostgreSQL License). `scripts/build-engine.ts` fetches the tag pinned in
69
+ `scripts/tool-versions.env` (`POSTGRES_SOURCE_TAG`), refuses it unless it
70
+ resolves to `POSTGRES_SOURCE_COMMIT`, and applies that patch and then the
71
+ [wasipg](https://github.com/moznion/wasipg) recipe's sjlj patches, checking each
72
+ before applying it. `scripts/patch-engine-source.ts` adds the di-framework
73
+ changes described in `engine/NOTICE`.
74
+
75
+ `make check-engine-patch` runs all of those steps without the container build,
76
+ in about 30 seconds. Run it first after bumping the PostgreSQL release: a patch
77
+ that no longer applies fails with its name, the base, and git's output. Then
78
+ follow [engine/patches/README.md](engine/patches/README.md).
79
+
62
80
  The build embeds the support filesystem, adapts the engine's WASI Preview 1
63
81
  imports to Preview 2, and composes the engine with the Rust database provider.
64
82
  It fails if the final artifact imports sockets or leaves the engine unresolved.
65
83
  Ship `dist/di-framework-pglite.wasm` together with `THIRD-PARTY-NOTICES.txt`.
66
84
  Build provenance and checksums are in `dist/BUILD-INFO.txt` and `SHA256SUMS`.
67
85
 
86
+ On one host architecture and one builder image, two clean engine builds are
87
+ byte-identical. `scripts/build-engine.ts` sets `SOURCE_DATE_EPOCH` to the commit
88
+ time of the pinned engine recipe (`PGLITE_SOURCE_REF`) and passes it into the
89
+ build container. OpenSSL then writes that date into `crypto/buildinf.h`
90
+ instead of the wall clock, so `libcrypto.a` is deterministic, and clang's
91
+ `__DATE__`/`__TIME__` are fixed. `engine/build-pgcrypto.sh` fails if
92
+ `buildinf.h` does not carry the pinned date. The engine does not link
93
+ OpenSSL's build info today, so this guards against it being linked in later.
94
+ `make reproducible` builds the engine twice from clean copies of the package
95
+ and fails unless `pglite.wasi`, `engine.core.wasm`, `engine.wasm` and every
96
+ embedded support file have the same sha256. The builds go in a new
97
+ `df-pglite-repro.*` directory under the system temp dir, or under
98
+ `REPRO_ARGS="--work-dir DIR"`, an existing directory outside the repository checkout.
99
+ Only that new directory is deleted, and it is kept if a build fails or the
100
+ digests differ. `--sdk-cache DIR` reuses SDK tarballs you have already
101
+ downloaded, and `--keep` keeps both builds. The
102
+ [reproducibility workflow](../../.github/workflows/pglite-engine-reproducible.yml)
103
+ runs the check on x86_64 when an engine input changes.
104
+
105
+ The results are not portable across these limits:
106
+ - An aarch64 host and an x86_64 host produce different engines and support
107
+ files, so an Apple Silicon build does not reproduce the released x86_64
108
+ engine.
109
+ - The builder image's `FROM debian:12` tag and its `apt-get` packages are not
110
+ pinned, so builds made months apart can differ.
111
+
68
112
  `make smoke` composes a real WIT consumer, runs it without network access, and
69
113
  checks typed parameters/results, SQL errors and recovery, transactions,
70
114
  rollback on close/drop, exclusive connection ownership, durability settings,
@@ -72,6 +116,14 @@ and persistence across separate runtime processes. It also exits a runtime
72
116
  with an open transaction and verifies that committed rows survive and the
73
117
  uncommitted row is absent after restart. No scripted database server is used.
74
118
 
119
+ `make smoke` also checks upgrades from the previous release. It downloads the
120
+ published `@di-framework/pglite-component` tarball pinned as
121
+ `PGLITE_UPGRADE_FROM_*` in `scripts/tool-versions.env` (6.0.15, PostgreSQL
122
+ 17.5) and checks its sha256. Its provider writes a data directory with a table,
123
+ pgcrypto and PGP ciphertext. The new build must then open that directory,
124
+ report 17.11, read the rows, decrypt the old ciphertext, run pgcrypto on new
125
+ values, and write to it.
126
+
75
127
  ## Publishing to GHCR
76
128
 
77
129
  The pglite component is published to GitHub Container Registry (GHCR) as an OCI wasm component. [The workflow](https://github.com/di-framework/platform/actions/workflows/pglite-component-publish.yml) runs by itself on each push to `main` that changes one of its input paths (`on.push.paths`). `workflow_dispatch` stays available for reruns and always builds.
@@ -79,7 +131,7 @@ The pglite component is published to GitHub Container Registry (GHCR) as an OCI
79
131
  The workflow has four jobs:
80
132
  - `check-source` (`packages: read`) hashes the committed input files (`scripts/source-check.ts`). On a push it skips the build when `ghcr.io/di-framework/pglite-component:src-<hash>` already exists, so commits that do not change the component publish nothing.
81
133
  - `build` (no write token) runs the same targets as `ci.yml`: `make tools-rust`, `make unit smoke` (which runs `make build`, composing the provider with the engine via `wac plug`), then the publisher crates' clippy and tests.
82
- - `publish` (`packages: write`) downloads the tested `dist/` and runs `pglite-component-publisher`. It never rebuilds or modifies `dist/`. It checks `SHA256SUMS`, requires the export `di-framework:pglite/database@0.2.0` and rejects any import that is not `wasi:*`, then pushes `ghcr.io/di-framework/pglite-component:<commit sha>` once, pulls it back by the manifest digest to compare bytes, then points the version tag (`0.2.0`, the WIT package version) at that same manifest with `oras tag` and asserts both tags resolve to one digest. The `build` job passes the tested wasm sha256 to `publish`, which verifies it before pushing. It also tags the manifest `src-<hash>`.
134
+ - `publish` (`packages: write`) downloads the tested `dist/` and runs `pglite-component-publisher`. It never rebuilds or modifies `dist/`. It checks `SHA256SUMS`, requires the export `di-framework:pglite/database@0.2.0` and rejects any import that is not `wasi:*`, then pushes the layer, config and manifest with `oras` under `ghcr.io/di-framework/pglite-component:<commit sha>` only, pulls it back with `wash` by the manifest digest to compare bytes, and only then points the version tag (`0.2.0`, the WIT package version) at that same manifest with `oras tag` and asserts both tags resolve to one digest. A failed check leaves the version tag where it was. The manifest and config carry a fixed `created` time (the publish step clears `SOURCE_DATE_EPOCH`, so `1970-01-01T00:00:00Z`), so publishing an unchanged `di-framework-pglite.wasm` gives the same digest and the pin job has nothing to pin. The `build` job passes the tested wasm sha256 to `publish`, which verifies it before pushing. It also tags the manifest `src-<hash>`.
83
135
  - `pin` (`contents: write`, `pull-requests: write`) opens or updates the PR `bot/pin-pglite-component`, "chore: pin pglite-component to <digest>", which rewrites the digests in this README with `scripts/pin-artifact.ts`. GitHub does not run workflows on a PR that `GITHUB_TOKEN` opened, so a maintainer has to start its checks (close and reopen it) before merging. It also runs when a push's source is already published (a revert to an older source, or a pin PR closed unmerged), so `main`'s pin follows the current source; it opens no PR when `main` already has the digest. On that path the `realign` job (`packages: write`) points the moving version tag back at that source's digest with `scripts/retag.sh`, which leaves a tag that is already there alone. Every tag move is behind the same source guard, so a stale run never retags.
84
136
 
85
137
  Tags are movable. `0.2.0` always points to the latest `main` publish for WIT package 0.2.0, and re-running a commit also moves its SHA tag. Only the `@sha256:...` digest is immutable, so consumers pin by digest.
@@ -87,7 +139,7 @@ Tags are movable. `0.2.0` always points to the latest `main` publish for WIT pac
87
139
  ### Artifact location
88
140
 
89
141
  The digest is in **Details** > **Record component digest** > **Step summary**, and in the `pglite-publish-report` artifact (`publish-report.json`).
90
- Published digest: `ghcr.io/di-framework/pglite-component@sha256:4c6243bed7c30df93ef5a6c11c3070e3e777786fe4e34b3a63f4b89b8f75a523`
142
+ Published digest: `ghcr.io/di-framework/pglite-component@sha256:9be0cc2f59efea9ade293173ca28bd289a5505eb31b08fb954e718c03316355e`
91
143
 
92
144
  **Note:** The GHCR package must be made public by an org admin after the first publish. Until then, only members with access to di-framework/platform can pull it.
93
145
 
@@ -125,7 +177,7 @@ wasmtime run --dir ./data::/data path/to/app.composed.wasm
125
177
  To use the published OCI component from GHCR instead (pin by digest for reproducibility):
126
178
 
127
179
  ```sh
128
- export PGLITE_REF='ghcr.io/di-framework/pglite-component@sha256:4c6243bed7c30df93ef5a6c11c3070e3e777786fe4e34b3a63f4b89b8f75a523'
180
+ export PGLITE_REF='ghcr.io/di-framework/pglite-component@sha256:9be0cc2f59efea9ade293173ca28bd289a5505eb31b08fb954e718c03316355e'
129
181
  wash oci pull "${PGLITE_REF}" pglite.wasm
130
182
  wac plug --plug pglite.wasm path/to/app.wasm -o path/to/app.composed.wasm
131
183
  mkdir -p ./data
@@ -210,13 +262,25 @@ PostgreSQL type:
210
262
  | `float4`, `float8` | `real` | |
211
263
  | `bytea` | `blob` | |
212
264
  | `json`, `jsonb` | `json` | JSON text; `jsonb` is re-rendered by PostgreSQL (`{"a": 1}`) |
213
- | `timestamptz` | `timestamp` | RFC 3339 in UTC, e.g. `2024-01-15T10:30:00Z`, fractional seconds kept (`...:00.123Z`). `infinity` and `-infinity` are returned as those literals; BC dates are returned unmodified (`0044-03-15 00:00:00+00 BC`) |
265
+ | `timestamptz` | `timestamp` | RFC 3339 in UTC, e.g. `2024-01-15T10:30:00Z`, fractional seconds kept (`...:00.123Z`). `infinity` and `-infinity` are returned as those literals. A value RFC 3339 cannot hold (BC dates, years after 9999) is `text`, as PostgreSQL printed it (`0044-03-15 00:00:00+00 BC`) |
214
266
  | `timestamp` (no zone) | `text` | `2024-01-15 10:30:00` (ISO, space separator, no offset). Deliberately not `timestamp`, which always denotes an instant |
215
267
  | `date` | `text` | `2024-01-15` |
216
268
  | `uuid`, `numeric` | `text` | canonical PostgreSQL text (`12.50` keeps its scale) |
217
269
  | arrays | `text` | PostgreSQL array literal, e.g. `{a,b}` |
218
270
  | everything else | `text` | |
219
271
 
272
+ A caller can still change either setting with `SET` for the rest of the connection. `timestamptz`
273
+ cells are parsed rather than trusted, so the `timestamp` variant always holds RFC 3339 in UTC (or
274
+ an infinity):
275
+
276
+ - After `SET TimeZone`, with `DateStyle` still ISO, PostgreSQL prints a local offset
277
+ (`2024-01-15 05:30:00.5-05`). The provider converts it back to UTC (`2024-01-15T10:30:00.5Z`).
278
+ - After `SET DateStyle` to `SQL`, `Postgres` or `German`, the output cannot be converted reliably
279
+ (`15/01/2024 05:30:00.5 EST`), so it is returned as `text`, exactly as printed. `infinity` and
280
+ `-infinity` print the same under every DateStyle, so they stay `timestamp`.
281
+
282
+ Closing and reopening the connection pins `DateStyle=ISO` and `TimeZone=UTC` again.
283
+
220
284
  Parameters are typed as follows. `integer`, `real`, `boolean` and `blob` are
221
285
  sent as `int8`, `float8`, `bool` and `bytea`. `text`, `json` and `timestamp`
222
286
  are all sent with OID 0 (unknown), so PostgreSQL infers the type from context:
@@ -269,6 +333,33 @@ engine routes to the host's WASI `random` interface. `gen_random_uuid()` is
269
333
  built into PostgreSQL and works without the extension. Other contrib modules
270
334
  are not included. The WIT interface does not change.
271
335
 
336
+ Public-key PGP (`pgp_pub_encrypt`/`pgp_pub_decrypt`) works with ElGamal and RSA
337
+ keys; pgcrypto cannot generate keys, so import them with `dearmor()`. For
338
+ ElGamal, the ephemeral `k` comes from OpenSSL's DRBG (`BN_rand`), not from
339
+ `pg_strong_random`. On WASI, OpenSSL seeds that DRBG from `getentropy`, which
340
+ is the same WASI `random_get` import. It fails closed: if the host cannot
341
+ supply entropy, the DRBG does not start and `pgp_pub_encrypt` raises an error
342
+ instead of using a weak `k`.
343
+
344
+ Blowfish (`bf`), CAST5 (`cast5`) and single DES (`des`) are unavailable in
345
+ this build, because the OpenSSL legacy provider is not built or loaded.
346
+ pgcrypto refuses them with `Cipher cannot be initialized`: in `encrypt()` and
347
+ `decrypt()`, in the PGP functions, and when decrypting PGP messages that use
348
+ them. For PGP this is upstream PostgreSQL's own check (17.11, CVE-2026-14663);
349
+ pgcrypto is otherwise unmodified. Provider releases before the #355 fix wrote
350
+ Blowfish and CAST5 PGP messages that are not actually encrypted. To recover such
351
+ a message, decrypt it once with upstream's `ignore-cipher-failure=1` option
352
+ (`pgp_sym_decrypt`, `pgp_pub_decrypt`; decryption only), then re-encrypt it with
353
+ AES. Plaintext recovered that way is not authenticated by the key. `3des` (DES-EDE3) is in OpenSSL's default provider and still works, for
354
+ legacy data only. Use `aes` (`aes128`, `aes192`, `aes256` for PGP). Password hashing with
355
+ `crypt()` and `gen_salt('bf')`, `'md5'`, `'xdes'` or `'des'` is unaffected,
356
+ because pgcrypto implements those itself.
357
+
358
+ The engine has no `dlopen`. Its emulation keeps a fixed table of 64 loaded
359
+ libraries per engine instance. pgcrypto resolves before that table and never
360
+ uses a slot. A `LOAD` of a new library after the table is full fails with
361
+ `dlopen table is full` and leaves the session usable.
362
+
272
363
  ## Persistence and ownership
273
364
 
274
365
  For an `open("/data/orders", ...)` call:
@@ -279,7 +370,8 @@ For an `open("/data/orders", ...)` call:
279
370
 
280
371
  Mount the entire root on persistent storage and reuse it after restarts.
281
372
  Initialization creates the cluster once; later starts reuse it. Incomplete
282
- clusters or an incompatible PostgreSQL major version are rejected.
373
+ clusters are rejected, and so is a data directory from another PostgreSQL major
374
+ version (see [below](#upgrading-across-postgresql-major-versions)).
283
375
  `fsync`, `synchronous_commit`, and `full_page_writes` are enabled before the
284
376
  backend starts. The host filesystem must honor WASI sync operations; a local
285
377
  restart test is not a power-loss durability certification.
@@ -310,6 +402,38 @@ its components the matching WASI preopen. Use a stable workload identity on
310
402
  redeploy and configure exclusive execution for this database. These
311
403
  annotations provide storage; they do not enforce database ownership.
312
404
 
405
+ ## Upgrading across PostgreSQL major versions
406
+
407
+ A data directory belongs to one PostgreSQL major version, recorded in
408
+ `<root>/data/PG_VERSION`. Minor releases share the on-disk format: a directory
409
+ written by the 17.5 engine (provider 6.0.15 and earlier) opens in place under
410
+ 17.11, and `make smoke` checks this.
411
+
412
+ The engine opens only major version 17. For any other `PG_VERSION`, `open`
413
+ fails with `open-failed` and a message such as:
414
+
415
+ ```text
416
+ incompatible PostgreSQL data directory: PG_VERSION is 16, but this provider bundles
417
+ PostgreSQL 17.11 and opens only major version 17 data directories; see
418
+ platform/pglite-component/README.md#upgrading-across-postgresql-major-versions
419
+ ```
420
+
421
+ The provider does not convert directories between major versions; it bundles
422
+ neither a second engine nor `pg_upgrade`. To move a database across a major
423
+ version:
424
+
425
+ 1. Stop every writer. Keep the provider version that wrote the directory,
426
+ pinned by its digest or npm version, and back up the whole root.
427
+ 2. With that provider, export the data through the application, for example
428
+ with a migration step that reads each table through the `database`
429
+ interface into a portable format.
430
+ 3. Deploy the new provider on a new, empty root, and recreate the schema with
431
+ the application's migrations.
432
+ 4. Import the exported data, check it, then retire the old root.
433
+
434
+ If the root is encrypted with `pglite-encfs`, compose encfs with the same key
435
+ for both the export and the import. PostgreSQL 18 is tracked in #401.
436
+
313
437
  ## Implementation
314
438
 
315
439
  - `js/adapter.ts`: the `SqlDatabase` adapter published on npm (`bun run build:adapter`).
@@ -318,7 +442,10 @@ annotations provide storage; they do not enforce database ownership.
318
442
  - `src/pgwire.rs`: PostgreSQL message encoding and typed rows, over memory.
319
443
  - `src/engine.rs`: persistent filesystem setup and exclusive engine access.
320
444
  - `engine/bridge.wat`: private canonical ABI bridge to the core engine.
321
- - `engine/build-pgcrypto.sh`: builds OpenSSL libcrypto and pgcrypto in the engine container and generates pgcrypto's static `dlsym` table; `scripts/patch-engine-source.ts` links both into the engine.
445
+ - `engine/build-pgcrypto.sh`: builds OpenSSL libcrypto and pgcrypto in the engine container and generates pgcrypto's static `dlsym` table; `scripts/patch-engine-source.ts` links both into the engine. The libcrypto build is cached under a key of the OpenSSL source tarball's sha256, the Configure options and `SOURCE_DATE_EPOCH`, so an OpenSSL version bump always rebuilds it.
446
+ - `scripts/patch-engine-source.ts`: also replaces the upstream `dlopen` emulation's unbounded table (`dltab`) with the bounded one described under [Extensions](#extensions), and keeps pgcrypto's hook ahead of it.
447
+ - `engine/patches/postgresql-17.11-wasi.patch`: Electric's 17.5 WASI changes replayed onto upstream `REL_17_11`; see [engine/patches/README.md](engine/patches/README.md).
448
+ - `scripts/build-engine.ts`: builds the engine source tree (pinned tag, checked commit, checked patches) and runs the wasipg container build; `scripts/check-engine-patch.ts` (`make check-engine-patch`) runs the same source steps without the build.
322
449
  - `scripts/prepare-engine.ts`: pinned engine preparation and componentization (all build scripts are Bun TypeScript; see `scripts/`).
323
450
  - `wit/deps/pglite-engine/engine.wit`: internal interface, composed away at build.
324
451
 
@@ -1,14 +1,16 @@
1
1
  component: di-framework:pglite@0.2.0
2
2
  profile: release
3
- built: 2026-10-13T22:17:05Z
3
+ built: 2026-10-16T17:04:13Z
4
4
  rustc: rustc 1.97.1 (8bab26f4f 2026-07-14)
5
5
  target: wasm32-wasip2
6
6
  wasm-tools: wasm-tools 1.258.0 (5c6d31c78 2026-08-24)
7
7
  wit-bindgen: 0.61.1
8
8
  md5: 0.7.0
9
- engine: PostgreSQL 17.5, persistent WASI filesystem
9
+ engine: PostgreSQL 17.11, persistent WASI filesystem
10
10
  extensions: plpgsql, pgcrypto (OpenSSL 3.5.9 libcrypto)
11
- engine-source: https://github.com/moznion/wasipg/tree/fa290be67946c0d3c4540bd1400b11e193d874e1
11
+ engine-source: https://github.com/postgres/postgres/tree/083ac033419f690758508e08c1736089384bbee8 (REL_17_11)
12
+ engine-patch: engine/patches/postgresql-17.11-wasi.patch (sha256 6beb64a561caa80e3669733f9e24e344edb0445d2623c17eee79d48ec28fac65)
13
+ engine-recipe: https://github.com/moznion/wasipg/tree/fa290be67946c0d3c4540bd1400b11e193d874e1
12
14
  adapter-sha256: e51dd61669a20daca34befe7fdadf1ac84e4795a2c84a8400818ee1de5373ccc
13
- engine-sha256: e0afe7bc67537c40ae37655df4722987e968784c45a3684ed35df2f19d86bdbf
14
- size: 20112680 bytes
15
+ engine-sha256: eb374344cff24c4cedacdad05a636a3b75b5eb1c4e55aa1a3ff9930be2ebc328
16
+ size: 20168533 bytes
package/dist/SHA256SUMS CHANGED
@@ -1,4 +1,4 @@
1
- 269169e596bc15f4cb5539bc9af85e58f6ac9bb090dd1ba05254878768c6b823 di-framework-pglite.wasm
1
+ a98a0476f61d539c72458be572d5705c8a237a49d51329784b65d564fab1b657 di-framework-pglite.wasm
2
2
  6053154ec1bc94de63ce4f4f4cce5922ef57dce794c2dde326f5845b8982d35f di-framework-pglite.wit
3
- 11f6ed49c8b63158770f1a4dea98780424ed9759ffa80a883f9efa5993bb7d29 BUILD-INFO.txt
4
- f57bcfb7d092565405081e910da9816b6b6a23d916c28542bf5d469e4bd31ff7 THIRD-PARTY-NOTICES.txt
3
+ f76f82266b1f741e10c5c89e6c30f620571adba6bb228a33324681d2dc1822b3 BUILD-INFO.txt
4
+ 443fd294671eb64972556656d3ee871e48448ad1169c012d18aa868568f628c1 THIRD-PARTY-NOTICES.txt
@@ -1,14 +1,22 @@
1
1
  di-framework embedded PGlite component
2
2
 
3
- The provider bundles PostgreSQL 17.5 (PGlite WASI), originally maintained by
4
- ElectricSQL. PostgreSQL's license is reproduced in POSTGRESQL-COPYRIGHT.
5
- The upstream bindings license and WASI adapter license are reproduced in
6
- PGLITE-BINDINGS-LICENSE and WASMTIME-LICENSE. The engine statically links
7
- the pgcrypto extension and OpenSSL libcrypto; their notices are in
8
- PGCRYPTO-NOTICES and the OpenSSL license (Apache-2.0) in OPENSSL-LICENSE.
3
+ The provider bundles PostgreSQL 17.11 built for WASI. The engine source is
4
+ upstream PostgreSQL REL_17_11 (commit 083ac033419f690758508e08c1736089384bbee8)
5
+ with ElectricSQL's PGlite WASI changes from postgres-pglite branch
6
+ REL_17_5_WASM-pglite (commit 2194acf356e9b7bf7cff29c4ed4bd6b82b93895d) replayed
7
+ onto it; that replay is engine/patches/postgresql-17.11-wasi.patch in the
8
+ di-framework source. PostgreSQL, postgres-pglite and the replay patch are
9
+ distributed under the PostgreSQL License, reproduced in POSTGRESQL-COPYRIGHT.
10
+ The engine is built with the wasipg recipe and its sjlj patches (Apache-2.0;
11
+ notice below). The upstream bindings license and WASI adapter license are
12
+ reproduced in PGLITE-BINDINGS-LICENSE and WASMTIME-LICENSE. The engine
13
+ statically links the pgcrypto extension and OpenSSL libcrypto; their notices
14
+ are in PGCRYPTO-NOTICES and the OpenSSL license (Apache-2.0) in
15
+ OPENSSL-LICENSE.
9
16
 
10
17
  Sources:
11
- https://github.com/electric-sql/postgres-pglite
18
+ https://github.com/postgres/postgres/tree/REL_17_11
19
+ https://github.com/electric-sql/postgres-pglite/tree/REL_17_5_WASM-pglite
12
20
  https://github.com/electric-sql/pglite-bindings
13
21
  https://github.com/moznion/wasipg
14
22
  https://github.com/bytecodealliance/wasmtime/tree/v29.0.1
@@ -20,7 +28,18 @@ ABI bridge, uses WASI randomness instead of a /dev/urandom preopen, and keeps
20
28
  bootstrap files within the database's persistent filesystem mount. A growable,
21
29
  bounded memory buffer replaces socket-file spillover for query replies. Backend
22
30
  startup restores application session defaults after bootstrap and enables
23
- durable writes.
31
+ durable writes. The emulated dlopen keeps loaded libraries in a bounded table
32
+ instead of writing past the end of an unsized array. Two small changes to the
33
+ WASI glue let it compile against 17.11: initdb's frontend SplitGUCList
34
+ declaration is renamed where initdb is compiled into the backend, and the
35
+ frontend allocator stubs gain the overflow-checked pg_malloc_mul and
36
+ pg_realloc_mul. pgcrypto is unmodified: PostgreSQL 17.11 itself refuses
37
+ ciphers OpenSSL cannot run (CVE-2026-14663), which in this build includes
38
+ Blowfish and CAST5.
39
+
40
+ The wasipg notice below describes wasipg's own release artifacts, which were
41
+ built from REL_17_5_WASM-pglite; this provider uses wasipg's build recipe and
42
+ patches with the 17.11 source tree above.
24
43
 
25
44
  The engine's core module, support files, adapter, and the provider are
26
45
  composed into one deployable artifact. Engine code executes in the Wasm
@@ -83,9 +102,9 @@ wasi-libc from wasi-sdk 33, distributed under
83
102
  "Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT". The shadow headers
84
103
  under build/hotfix/ are derived from wasi-libc headers.
85
104
  PostgreSQL Database Management System
86
- (formerly known as Postgres, then as Postgres95)
105
+ (also known as Postgres, formerly known as Postgres95)
87
106
 
88
- Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
107
+ Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
89
108
 
90
109
  Portions Copyright (c) 1994, The Regents of the University of California
91
110
 
@@ -107,7 +126,7 @@ ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
107
126
  PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
108
127
 
109
128
  --------------------------------------------------------------------------
110
- pgcrypto (PostgreSQL 17.5 contrib/pgcrypto)
129
+ pgcrypto (PostgreSQL 17.11 contrib/pgcrypto)
111
130
  --------------------------------------------------------------------------
112
131
 
113
132
  pgcrypto is part of PostgreSQL and is distributed under the PostgreSQL
@@ -118,6 +137,7 @@ distribution.
118
137
  px.c, px-hmac.c, px-crypt.c, mbuf.c, openssl.c, pgcrypto.c, pgp*.c and
119
138
  their headers:
120
139
 
140
+ Copyright (c) 2000 Marko Kreen
121
141
  Copyright (c) 2001 Marko Kreen
122
142
  Copyright (c) 2005 Marko Kreen
123
143
  All rights reserved.
Binary file
@@ -100,7 +100,8 @@ export declare function toWasmPgValue(value: unknown): WasmPgValue;
100
100
  /**
101
101
  * Formats a `timestamp` variant the way the `wasmcloud:postgres` codec does:
102
102
  * `YYYY-MM-DDTHH:MM:SS.mmmZ`. Microseconds are truncated to milliseconds.
103
- * `infinity`, `-infinity`, and BC dates are returned unchanged.
103
+ * `infinity` and `-infinity` are returned unchanged. (The provider returns BC dates and other
104
+ * values it cannot express in RFC 3339 as `text`, so they never reach this function.)
104
105
  */
105
106
  export declare function pgliteTimestampIso(value: string): string;
106
107
  /** Converts a `value` variant into what the `wasmcloud:postgres` codec in `@di-framework/repo` returns. */
@@ -141,7 +141,8 @@ const RFC3339_UTC = /^(\d{4,}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.(\d+))?Z$/;
141
141
  /**
142
142
  * Formats a `timestamp` variant the way the `wasmcloud:postgres` codec does:
143
143
  * `YYYY-MM-DDTHH:MM:SS.mmmZ`. Microseconds are truncated to milliseconds.
144
- * `infinity`, `-infinity`, and BC dates are returned unchanged.
144
+ * `infinity` and `-infinity` are returned unchanged. (The provider returns BC dates and other
145
+ * values it cannot express in RFC 3339 as `text`, so they never reach this function.)
145
146
  */
146
147
  export function pgliteTimestampIso(value) {
147
148
  const match = RFC3339_UTC.exec(value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@di-framework/pglite-component",
3
- "version": "6.0.14",
3
+ "version": "6.0.16",
4
4
  "type": "module",
5
5
  "description": "Embedded PostgreSQL component with persistent WASI storage and no TCP, plus its SqlDatabase adapter for @di-framework/repo.",
6
6
  "license": "(MIT OR Apache-2.0)",
package/wit/world.wit CHANGED
@@ -60,7 +60,12 @@ interface types {
60
60
  /// - `json` and `jsonb` -> `json` (JSON text).
61
61
  /// - `timestamptz` -> `timestamp`, RFC 3339 in UTC (`2024-01-15T10:30:00Z`,
62
62
  /// fractional seconds kept). `infinity` and `-infinity` are returned as
63
- /// those literals.
63
+ /// those literals. This holds after a caller's own `SET TimeZone`: any
64
+ /// ISO output is converted back to UTC. A value that cannot be converted
65
+ /// (BC dates, years after 9999, or any output after `SET DateStyle` to
66
+ /// `SQL`, `Postgres` or `German`) is returned as `text`, as PostgreSQL
67
+ /// printed it. `infinity` and `-infinity` stay `timestamp` under every
68
+ /// DateStyle. Reopening the connection pins both settings again.
64
69
  /// - `timestamp` (no zone) and `date` -> `text` (`2024-01-15 10:30:00`,
65
70
  /// `2024-01-15`).
66
71
  /// - `uuid` and `numeric` -> `text`; arrays -> `text` as PostgreSQL array
@@ -109,7 +114,7 @@ interface database {
109
114
  /// are supported. Close/drop releases the connection for reuse at that root.
110
115
  open: func(path: string, options: option<open-options>) -> result<connection, error>;
111
116
 
112
- /// The bundled engine version string, `17.5`; does not open a database.
117
+ /// The bundled engine version string, `17.11`; does not open a database.
113
118
  server-version: func() -> result<string, error>;
114
119
 
115
120
  /// An exclusive handle to the embedded session. Closing or dropping it