@crvouga/mockingbird-service-postgres 3.4.0 → 3.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog — @crvouga/mockingbird-service-postgres
2
2
 
3
+ ## 3.4.1 (2026-10-15)
4
+
5
+ ### Fixes and improvements
6
+
7
+ - resolve snapshot, promotion and webhook issues ([75fb79f](https://github.com/crvouga/mockingbird/commit/75fb79f9a999bf0af29c4ec07fde4f1d7a1f0c22))
8
+
3
9
  ## 3.4.0 (2026-10-12)
4
10
 
5
11
  ### Features
package/COMPATIBILITY.md CHANGED
@@ -58,7 +58,7 @@ for the guarantees and their limits (`tests/wire/durable*.test.ts`, `tests/wire/
58
58
 
59
59
  Anything a PostgreSQL application can invoke through SQL against the PGlite **18.3** oracle must match observable behavior, except:
60
60
 
61
- 1. **Snapshot format** — custom binary codec (`PGMM`), not `pg_dump` / on-disk clusters (logical state still round-trips).
61
+ 1. **Snapshot format** — custom binary codec (`PGMM`), not `pg_dump` / on-disk clusters (logical state still round-trips). Decoding PGMM v3 preserves bigint-backed SQL datums (including small `bigint`, `money`, `time`, `timestamp`, and `timestamptz` values) using their catalog types, so arithmetic remains valid after repeated restores, including materialized views (`tests/contract/snapshots/basic.test.ts`).
62
62
  2. **Deterministic `random()` / `now()`** — seeded PRNG and fixed clock by default (injectable).
63
63
  3. **Single-session sync API** — no concurrent sessions or `25P02` aborted-transaction state. The optional wire server separately provides per-session `READ COMMITTED` workspaces and row locks.
64
64
  4. **NOT APPLICABLE** rows in `compat/coverage.json` (roles, replication, VACUUM internals, LISTEN/NOTIFY, cursors, full PL/pgSQL, extensions other than `pgcrypto`'s `digest()` and `pg_trgm`'s `similarity` / `<%` / `gin_trgm_ops`).
package/dist/index.js CHANGED
@@ -26670,7 +26670,7 @@ function readSlabCell(column, rowIndex, intern, rowCount) {
26670
26670
  }
26671
26671
  if (pack === PACK_INT) {
26672
26672
  const integer = view.getBigInt64(nonNullIndex * 8, true);
26673
- return integer <= BigInt(Number.MAX_SAFE_INTEGER) && integer >= BigInt(Number.MIN_SAFE_INTEGER) ? Number(integer) : integer;
26673
+ return !column.integerBigInt && integer <= BigInt(Number.MAX_SAFE_INTEGER) && integer >= BigInt(Number.MIN_SAFE_INTEGER) ? Number(integer) : integer;
26674
26674
  }
26675
26675
  if (pack === PACK_TEXT_INTERN) {
26676
26676
  const id = view.getUint32(nonNullIndex * 4, true);
@@ -27231,7 +27231,8 @@ function decodeInner(snapshot, prng, clock) {
27231
27231
  if (meta.stats) state.tableStats.set(table.oid, meta.stats);
27232
27232
  const rowCount = readVarintU32(r);
27233
27233
  const slabColumns = [];
27234
- for (let c = 0; c < meta.columns.length; c++) slabColumns.push(readPackedColumn(r, rowCount, intern));
27234
+ for (let c = 0; c < meta.columns.length; c++)
27235
+ slabColumns.push(readPackedColumn(r, rowCount, intern, meta.columns[c].type.id));
27235
27236
  table.attachSlab(new ColumnarSlab(snapshot, rowCount, slabColumns, intern));
27236
27237
  schema.tables.set(table.name, table);
27237
27238
  }
@@ -27244,7 +27245,7 @@ function decodeInner(snapshot, prng, clock) {
27244
27245
  const matRowCount = readVarintU32(r);
27245
27246
  const width = readVarintU32(r);
27246
27247
  const cols = [];
27247
- for (let c = 0; c < width; c++) cols.push(readPackedColumn(r, matRowCount, intern));
27248
+ for (let c = 0; c < width; c++) cols.push(readPackedColumn(r, matRowCount, intern, meta.matColumns?.[c]?.type));
27248
27249
  const slab = new ColumnarSlab(snapshot, matRowCount, cols, intern);
27249
27250
  matRows = slab.materialize();
27250
27251
  }
@@ -27516,7 +27517,7 @@ function writePackedColumn(w, rows, col, internId, forceId) {
27516
27517
  writeTaggedDatum(w, rows[i][col], internId, forceId);
27517
27518
  }
27518
27519
  }
27519
- function readPackedColumn(r, n, intern) {
27520
+ function readPackedColumn(r, n, intern, type) {
27520
27521
  const pack = r.u8();
27521
27522
  if (pack === PACK_NULL) return { pack, nullBitmap: null, payload: new Uint8Array(0) };
27522
27523
  const bits = r.raw(n + 7 >> 3);
@@ -27529,7 +27530,8 @@ function readPackedColumn(r, n, intern) {
27529
27530
  r.skipAlign4();
27530
27531
  const width = 8;
27531
27532
  const payload = r.raw(nonNull * width);
27532
- return { pack, nullBitmap: bits, payload };
27533
+ const integerBigInt = type !== void 0 && ["int8", "money", "time", "timestamp", "timestamptz"].includes(type);
27534
+ return { pack, nullBitmap: bits, payload, integerBigInt };
27533
27535
  }
27534
27536
  if (pack === PACK_TEXT_INTERN) {
27535
27537
  r.skipAlign4();