@voltro/sql-postgres 0.33.0 → 0.35.0

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/dist/index.js CHANGED
@@ -1,39 +1,47 @@
1
1
  import { PgClient as e, PgClient as t } from "@effect/sql-pg";
2
- import { Config as n, Effect as r, Fiber as i, Layer as a, ManagedRuntime as o, Option as s, Redacted as c, Schedule as l, Stream as u } from "effect";
3
- import d from "pg";
4
- import { EventEmitter as f } from "node:events";
5
- import { createLogger as p } from "@voltro/logger";
6
- import { SqlClient as m, TransactionConnection as h } from "@effect/sql/SqlClient";
7
- import { EagerCardinalityError as g, attachEagerLoads as _, attributionFields as v, attributionKey as y, beginLocalWrite as b, compileEagerJson as x, compilePredicate as S, compileRawFragment as C, compileSelect as w, currentWriteAttribution as T, encodeRowForSchema as E, endLocalWrite as D, hasEagerLoads as O, isTableReactive as k, raiseChangeListenerCeiling as A, recordsTable as j, registerPendingAttribution as M, requireTable as N, resolveEchoAttribution as P, runWithWriteAttribution as ee, runWriteRecorders as te, settleTransactionExit as ne, stampGeneratedId as F, stampGeneratedIds as I, withCapturedAttribution as L } from "@voltro/database";
8
- var R = (e) => e ? { rejectUnauthorized: !1 } : !1, z = /^[A-Za-z_][A-Za-z0-9_]*$/, B = (t) => {
9
- if (t.schema === void 0 && t.statementTimeoutMs === void 0) return e.layerConfig({
10
- host: n.succeed(t.host),
11
- port: n.succeed(t.port),
12
- username: n.succeed(t.username),
13
- password: n.succeed(c.make(t.password)),
14
- database: n.succeed(t.database),
15
- ...t.maxConnections === void 0 ? {} : { maxConnections: n.succeed(t.maxConnections) },
16
- ...t.ssl === void 0 ? {} : { ssl: n.succeed(R(t.ssl)) }
17
- });
18
- let i = {};
2
+ import { Config as n, Duration as r, Effect as i, Fiber as a, Layer as o, ManagedRuntime as s, Metric as c, Redacted as l, Schedule as u, Stream as d } from "effect";
3
+ import f from "pg";
4
+ import { DEFAULT_ACQUIRE_TIMEOUT_MS as p, EagerCardinalityError as m, attachEagerLoads as h, attributionFields as g, attributionKey as ee, beginLocalWrite as te, bulkInsertLimitsFor as ne, chunkRowsForInsert as re, compileEagerJson as ie, compilePredicate as _, compileRawFragment as ae, compileSelect as oe, encodeRowForSchema as v, endLocalWrite as se, externalChangeEvent as ce, hasEagerLoads as le, isTableReactive as y, makeEagerFallbackReporter as ue, observeDbOp as b, raiseChangeListenerCeiling as de, recordsTable as fe, registerPendingAttribution as x, requireTable as S, resolveEchoAttribution as C, runRetryingTransaction as w, runStoreTransaction as T, runWriteRecorders as pe, stampGeneratedId as E, stampGeneratedIds as me, withCapturedAttribution as D } from "@voltro/database";
5
+ import { EventEmitter as he } from "node:events";
6
+ import { createLogger as ge } from "@voltro/logger";
7
+ import { SqlClient as O, TransactionConnection as k } from "@effect/sql/SqlClient";
8
+ //#region src/sqlLayer.ts
9
+ var A = (e) => {
10
+ let t = e.acquireTimeoutMs ?? p;
11
+ return t > 0 ? t : void 0;
12
+ }, j = (e) => e ? { rejectUnauthorized: !1 } : !1, M = /^[A-Za-z_][A-Za-z0-9_]*$/, N = (e) => {
13
+ let t = A(e);
14
+ return {
15
+ host: n.succeed(e.host),
16
+ port: n.succeed(e.port),
17
+ username: n.succeed(e.username),
18
+ password: n.succeed(l.make(e.password)),
19
+ database: n.succeed(e.database),
20
+ ...e.maxConnections === void 0 ? {} : { maxConnections: n.succeed(e.maxConnections) },
21
+ ...e.ssl === void 0 ? {} : { ssl: n.succeed(j(e.ssl)) },
22
+ ...t === void 0 ? {} : { connectTimeout: n.succeed(r.millis(t)) }
23
+ };
24
+ }, P = (t) => {
25
+ if (t.schema === void 0 && t.statementTimeoutMs === void 0) return e.layerConfig(N(t));
26
+ let n = {};
19
27
  if (t.schema !== void 0) {
20
- if (!z.test(t.schema)) throw Error(`DB_SCHEMA '${t.schema}' is not a valid postgres identifier (expected ${z}).`);
21
- i = { options: `-c search_path="${t.schema}"` };
28
+ if (!M.test(t.schema)) throw Error(`DB_SCHEMA '${t.schema}' is not a valid postgres identifier (expected ${M}).`);
29
+ n = { options: `-c search_path="${t.schema}"` };
22
30
  }
23
- let a = r.acquireRelease(r.sync(() => new d.Pool({
31
+ let r = A(t), a = i.acquireRelease(i.sync(() => new f.Pool({
24
32
  host: t.host,
25
33
  port: t.port,
26
34
  user: t.username,
27
35
  password: t.password,
28
36
  database: t.database,
29
37
  ...t.maxConnections === void 0 ? {} : { max: t.maxConnections },
30
- ...t.ssl === void 0 ? {} : { ssl: R(t.ssl) },
38
+ ...t.ssl === void 0 ? {} : { ssl: j(t.ssl) },
31
39
  ...t.statementTimeoutMs === void 0 ? {} : { statement_timeout: t.statementTimeoutMs },
32
- connectionTimeoutMillis: t.acquireTimeoutMs ?? 1e4,
33
- ...i
34
- })), (e) => r.promise(() => e.end()));
40
+ ...r === void 0 ? {} : { connectionTimeoutMillis: r },
41
+ ...n
42
+ })), (e) => i.promise(() => e.end()));
35
43
  return e.layerFromPool({ acquire: a });
36
- }, V = (e) => {
44
+ }, F = (e) => {
37
45
  let t = e.get("sslmode");
38
46
  if (t !== null) {
39
47
  if (t === "require") return !0;
@@ -46,19 +54,20 @@ var R = (e) => e ? { rejectUnauthorized: !1 } : !1, z = /^[A-Za-z_][A-Za-z0-9_]*
46
54
  if (n === "false" || n === "0") return !1;
47
55
  throw Error(`DB_URL '?ssl=${n}' is not supported by the postgres dialect — use 'true'/'1' or 'false'/'0'.`);
48
56
  }
49
- }, H = (e) => {
50
- let t = e.schema === void 0 ? {} : { schema: e.schema };
57
+ }, I = (e) => {
58
+ let t = e.schema === void 0 ? {} : { schema: e.schema }, n = e.acquireTimeoutMs === void 0 ? {} : { acquireTimeoutMs: e.acquireTimeoutMs };
51
59
  if (e.url) {
52
- let n = new URL(e.url), r = e.ssl ?? V(n.searchParams);
60
+ let r = new URL(e.url), i = e.ssl ?? F(r.searchParams);
53
61
  return {
54
- host: n.hostname || "localhost",
55
- port: n.port ? Number(n.port) : 5432,
56
- username: decodeURIComponent(n.username || "app"),
57
- password: decodeURIComponent(n.password || "app"),
58
- database: n.pathname.replace(/^\//, "") || "app",
62
+ host: r.hostname || "localhost",
63
+ port: r.port ? Number(r.port) : 5432,
64
+ username: decodeURIComponent(r.username || "app"),
65
+ password: decodeURIComponent(r.password || "app"),
66
+ database: r.pathname.replace(/^\//, "") || "app",
59
67
  ...e.maxConnections === void 0 ? {} : { maxConnections: e.maxConnections },
60
68
  ...e.statementTimeoutMs === void 0 ? {} : { statementTimeoutMs: e.statementTimeoutMs },
61
- ...r === void 0 ? {} : { ssl: r },
69
+ ...i === void 0 ? {} : { ssl: i },
70
+ ...n,
62
71
  ...t
63
72
  };
64
73
  }
@@ -71,170 +80,271 @@ var R = (e) => e ? { rejectUnauthorized: !1 } : !1, z = /^[A-Za-z_][A-Za-z0-9_]*
71
80
  ...e.maxConnections === void 0 ? {} : { maxConnections: e.maxConnections },
72
81
  ...e.statementTimeoutMs === void 0 ? {} : { statementTimeoutMs: e.statementTimeoutMs },
73
82
  ...e.ssl === void 0 ? {} : { ssl: e.ssl },
83
+ ...n,
74
84
  ...t
75
85
  };
76
- }, U = (e) => B(H(e)), W = /* @__PURE__ */ new Set(["40001", "40P01"]), G = (e) => {
86
+ }, L = (e) => P(I(e)), R = /* @__PURE__ */ new Set(["40001", "40P01"]), _e = (e) => {
77
87
  let t = e;
78
88
  for (let e = 0; e < 5 && typeof t == "object" && t; e++) {
79
89
  let e = t.code;
80
90
  if (typeof e == "string") return e;
81
91
  t = t.cause;
82
92
  }
83
- }, K = (e) => {
84
- let t = G(e);
85
- return t !== void 0 && W.has(t);
86
- }, q = (e) => K(e) ? "retry" : "noRetry", J = ["json"], Y = p({ scope: "voltro:postgres" }), X = async (e) => {
87
- let t = e.tracerLayer ? a.mergeAll(e.sqlLayer, e.tracerLayer) : e.sqlLayer, n = o.make(t), r = await n.runPromise(m), i = e.changeStrategy ?? "inline", s = new re(r, n, i, e.cdcChannel ?? "framework_changes");
88
- return i === "cdc" && await s.startCdcConsumer(), s;
89
- }, Z = () => {
90
- let e = T();
91
- return e === void 0 ? (e) => e() : (t) => ee(e, t);
92
- }, re = class {
93
+ }, z = (e) => {
94
+ let t = _e(e);
95
+ return t !== void 0 && R.has(t);
96
+ }, B = (e) => z(e) ? "retry" : "noRetry", V = c.counter("voltro_cdc_oversized_total", { description: "Change events whose row images exceeded the postgres NOTIFY payload cap, by what re-hydration recovered (rehydrated = row re-read · tombstone = delete, primary key only · unrecovered = content lost to taps)." }), ve = {
97
+ rehydrated: c.tagged(V, "outcome", "rehydrated"),
98
+ tombstone: c.tagged(V, "outcome", "tombstone"),
99
+ unrecovered: c.tagged(V, "outcome", "unrecovered")
100
+ }, H = (e) => {
101
+ i.runSync(c.increment(ve[e]));
102
+ }, ye = {
103
+ rehydrateTimeoutMs: 5e3,
104
+ rehydrateRetries: 2
105
+ }, U = (e) => {
106
+ let t = process.env[e];
107
+ if (t === void 0 || t.trim() === "") return;
108
+ let n = Number(t);
109
+ return Number.isFinite(n) && n >= 0 ? n : void 0;
110
+ }, W = (e) => {
111
+ let t = ye, n = e ?? {};
112
+ return {
113
+ rehydrateTimeoutMs: Math.max(1, n.rehydrateTimeoutMs ?? U("VOLTRO_CDC_REHYDRATE_TIMEOUT_MS") ?? t.rehydrateTimeoutMs),
114
+ rehydrateRetries: Math.max(0, n.rehydrateRetries ?? U("VOLTRO_CDC_REHYDRATE_RETRIES") ?? t.rehydrateRetries)
115
+ };
116
+ }, be = (e) => i.suspend(() => {
117
+ let t = e.notification, n = t.id, a = {
118
+ table: t.table,
119
+ op: t.op
120
+ }, o = (e) => ({
121
+ event: {
122
+ ...a,
123
+ old: null,
124
+ new: null,
125
+ oversized: "unrecovered"
126
+ },
127
+ outcome: "unrecovered",
128
+ reason: e
129
+ });
130
+ if (typeof n != "string" && typeof n != "number") return H("unrecovered"), i.succeed(o("no-key"));
131
+ if (t.op === "delete") {
132
+ H("tombstone");
133
+ let e = {
134
+ event: {
135
+ ...a,
136
+ old: { id: n },
137
+ new: null,
138
+ oversized: "tombstone"
139
+ },
140
+ outcome: "tombstone"
141
+ };
142
+ return i.succeed(e);
143
+ }
144
+ let s = u.exponential(r.millis(50), 2).pipe(u.intersect(u.recurs(e.tunables.rehydrateRetries)));
145
+ return e.fetchRow({
146
+ schema: t.schema,
147
+ table: t.table,
148
+ key: n
149
+ }).pipe(i.retry(s), i.timeout(r.millis(e.tunables.rehydrateTimeoutMs)), i.map((e) => e === null ? (H("unrecovered"), o("row-gone")) : (H("rehydrated"), {
150
+ event: {
151
+ ...a,
152
+ old: null,
153
+ new: e,
154
+ oversized: "rehydrated"
155
+ },
156
+ outcome: "rehydrated"
157
+ })), i.catchAllCause(() => (H("unrecovered"), i.succeed(o("read-failed")))));
158
+ }), xe = (e) => {
159
+ let t = /* @__PURE__ */ new Set();
160
+ return (n, r) => {
161
+ if (r.outcome === "unrecovered") {
162
+ e.error("cdc: oversized change could not be recovered — every tap (search, analytics, cdc-out, history) will miss this row; subscriptions re-query and are unaffected", {
163
+ table: n.table,
164
+ op: n.op,
165
+ reason: r.reason,
166
+ ...r.reason === "no-key" ? { remedy: "run `voltro db apply` — this database's change-notify function predates the key" } : {}
167
+ });
168
+ return;
169
+ }
170
+ t.has(n.table) || (t.add(n.table), e.warn("cdc: rows on this table exceed the postgres NOTIFY payload cap (8000 bytes) — their change events are re-read from the database before delivery. Counted as voltro_cdc_oversized_total.", {
171
+ table: n.table,
172
+ outcome: r.outcome,
173
+ note: r.outcome === "tombstone" ? "a delete of an oversized row delivers the primary key only — the pre-image is unrecoverable" : "the re-read returns the row as it is NOW, not the image at commit"
174
+ }));
175
+ };
176
+ }, G = ["json"], K = ge({ scope: "voltro:postgres" }), q = async (e) => {
177
+ let t = e.tracerLayer ? o.mergeAll(e.sqlLayer, e.tracerLayer) : e.sqlLayer, n = s.make(t), r = await n.runPromise(O), i = e.changeStrategy ?? "inline", a = new Se(r, n, i, e.cdcChannel ?? "framework_changes", W({
178
+ ...e.cdcRehydrateTimeoutMs === void 0 ? {} : { rehydrateTimeoutMs: e.cdcRehydrateTimeoutMs },
179
+ ...e.cdcRehydrateRetries === void 0 ? {} : { rehydrateRetries: e.cdcRehydrateRetries }
180
+ }));
181
+ return i === "cdc" && await a.startCdcConsumer(), a;
182
+ }, Se = class {
93
183
  sql;
94
184
  runtime;
95
185
  changeStrategy;
96
186
  cdcChannel;
97
- emitter = new f();
187
+ cdcRehydrate;
188
+ emitter = new he();
98
189
  cdcFiber = null;
99
190
  inflightTxns = 0;
100
- constructor(e, t, n, r) {
101
- this.sql = e, this.runtime = t, this.changeStrategy = n, this.cdcChannel = r, A(this.emitter);
191
+ reportOversized = xe(K);
192
+ reportEagerFallback = ue(K);
193
+ constructor(e, t, n, r, i = W()) {
194
+ this.sql = e, this.runtime = t, this.changeStrategy = n, this.cdcChannel = r, this.cdcRehydrate = i, de(this.emitter);
195
+ }
196
+ txnSpec(e, t, n) {
197
+ return {
198
+ label: e,
199
+ dialect: "postgres",
200
+ withTransaction: (e) => this.sql.withTransaction(e),
201
+ runPromiseExit: (e) => this.runtime.runPromiseExit(e),
202
+ isRetryable: z,
203
+ span: {
204
+ name: t,
205
+ attributes: {
206
+ "db.system": "postgresql",
207
+ "db.operation": n
208
+ }
209
+ }
210
+ };
102
211
  }
103
212
  withNamespace(e) {
104
- return e === null ? this : new ie(this, e);
213
+ return e === null ? this : new Ce(this, e);
105
214
  }
106
215
  async runInNamespace(e, t) {
216
+ let n = this.sql;
107
217
  this.inflightTxns++;
108
- let n = T(), i = Z(), a = this.sql, o = this.sql.withTransaction(r.flatMap(r.serviceOption(h), (o) => {
109
- if (s.isNone(o)) return r.fail(/* @__PURE__ */ Error("PostgresDataStore.runInNamespace: TransactionConnection missing."));
110
- let c = o.value, l = r.provideService(a`SET LOCAL search_path TO ${a(e)}`, h, c), u = new Q(this, c, n);
111
- return r.flatMap(l, () => r.tryPromise({
112
- try: () => i(() => t(u)).then((e) => ({
113
- result: e,
114
- view: u
115
- })),
116
- catch: (e) => e
117
- }));
118
- })).pipe(r.withSpan("store.namespace", { attributes: {
119
- "db.system": "postgresql",
120
- "db.operation": "namespace.transaction"
121
- } }));
122
218
  try {
123
- let e = await this.runtime.runPromise(o);
124
- return e.view.commitEvents(), e.result;
219
+ return await T({
220
+ ...this.txnSpec("PostgresDataStore.runInNamespace", "store.namespace", "namespace.transaction"),
221
+ prepare: (t) => i.provideService(n`SET LOCAL search_path TO ${n(e)}`, k, t),
222
+ work: t,
223
+ makeView: (e, t) => new J(this, e, t)
224
+ });
125
225
  } finally {
126
226
  this.inflightTxns--;
127
227
  }
128
228
  }
129
229
  __postgresReplicationFriend = { runEffect: (e) => this.runtime.runPromise(e) };
130
- async executeQuery(e, t) {
131
- let n = w(e, this.sql), i = t ? r.provideService(n, h, t) : n;
132
- return this.runtime.runPromise(i);
230
+ async executeQuery(e, t, n = null) {
231
+ let r = oe(e, this.sql, n), a = t ? i.provideService(r, k, t) : r;
232
+ return b("postgres", "select", () => this.runtime.runPromise(a));
133
233
  }
134
- async executeInsert(e, t, n, i, a) {
135
- t = F(e, t);
136
- let o = this.sql, s = o`INSERT INTO ${o(e)} ${o.insert(E(t, e, J))} RETURNING *`, c = n ? r.provideService(s, h, n) : s, l = (await this.runtime.runPromise(c))[0];
234
+ async executeInsert(e, t, n, r, a) {
235
+ t = E(e, t);
236
+ let o = this.sql, s = o`INSERT INTO ${o(e)} ${o.insert(v(t, e, G))} RETURNING *`, c = n ? i.provideService(s, k, n) : s, l = (await this.runtime.runPromise(c))[0];
137
237
  if (!l) throw Error(`PostgresDataStore.insert: no row returned for table '${e}'`);
138
238
  return await this.routeEvent({
139
239
  table: e,
140
240
  op: "insert",
141
241
  old: null,
142
242
  new: l
143
- }, i, n, a), l;
243
+ }, r, n, a), l;
144
244
  }
145
- async executeUpdate(e, t, n, i, a, o) {
146
- let s = this.sql, c = s`UPDATE ${s(e)} SET ${s.update(E(n, e, J))} WHERE ${s("id")} = ${t} RETURNING *`, l = i ? r.provideService(c, h, i) : c, u = (await this.runtime.runPromise(l))[0];
245
+ async executeUpdate(e, t, n, r, a, o) {
246
+ let s = this.sql, c = s`UPDATE ${s(e)} SET ${s.update(v(n, e, G))} WHERE ${s("id")} = ${t} RETURNING *`, l = r ? i.provideService(c, k, r) : c, u = (await this.runtime.runPromise(l))[0];
147
247
  return u ? (await this.routeEvent({
148
248
  table: e,
149
249
  op: "update",
150
250
  old: null,
151
251
  new: u
152
- }, a, i, o), u) : null;
252
+ }, a, r, o), u) : null;
153
253
  }
154
- async executeUpsert(e, t, n, i, a, o) {
155
- let c = this.sql;
254
+ async executeUpsert(e, t, n, r, a, o) {
255
+ let s = this.sql;
156
256
  if (typeof n.update == "function") {
157
- let o = n.update, u = n.conflictColumns.map((e) => c`${c(e)} = ${t[e]}`), d = (n) => {
158
- let i = c`SELECT * FROM ${c(e)} WHERE ${c.and(u)} LIMIT 1 FOR UPDATE`;
159
- return this.runtime.runPromise(r.flatMap(r.provideService(i, h, n), (i) => r.promise(() => i[0] ? this.executeUpdate(e, i[0].id, o(i[0]), n, a).then((e) => e) : this.executeInsert(e, t, n, a))));
257
+ let o = n.update, c = n.conflictColumns.map((e) => s`${s(e)} = ${t[e]}`), l = (n) => {
258
+ let r = s`SELECT * FROM ${s(e)} WHERE ${s.and(c)} LIMIT 1 FOR UPDATE`;
259
+ return this.runtime.runPromise(i.flatMap(i.provideService(r, k, n), (r) => i.promise(() => r[0] ? this.executeUpdate(e, r[0].id, o(r[0]), n, a).then((e) => e) : this.executeInsert(e, t, n, a))));
160
260
  };
161
- if (i) return d(i);
261
+ if (r) return l(r);
162
262
  this.inflightTxns++;
163
263
  try {
164
- let e = r.suspend(() => this.sql.withTransaction(r.flatMap(r.serviceOption(h), (e) => s.isNone(e) ? r.fail(/* @__PURE__ */ Error("PostgresDataStore.upsert: TransactionConnection missing.")) : r.promise(() => d(e.value))))), t = l.exponential("10 millis").pipe(l.compose(l.recurs(3)), l.whileInput(K));
165
- return await this.runtime.runPromise(e.pipe(r.retry(t)));
264
+ return await w({
265
+ ...this.txnSpec("PostgresDataStore.upsert", "store.upsert", "upsert.transaction"),
266
+ body: (e) => l(e)
267
+ });
166
268
  } finally {
167
269
  this.inflightTxns--;
168
270
  }
169
271
  }
170
- let u = n.conflictColumns.map((e) => c`${c(e)}`), d = Object.keys(t).filter((e) => t[e] !== void 0), f = n.update === void 0 ? d.filter((e) => e !== "id" && !n.conflictColumns.includes(e)) : n.update, p = f.length > 0 ? c.csv(f.map((e) => c`${c(e)} = EXCLUDED.${c(e)}`)) : c`${c(n.conflictColumns[0])} = EXCLUDED.${c(n.conflictColumns[0])}`, m = c`INSERT INTO ${c(e)} ${c.insert(E(t, e, J))} ON CONFLICT (${c.csv(u)}) DO UPDATE SET ${p} RETURNING *`, g = i ? r.provideService(m, h, i) : m, _ = (await this.runtime.runPromise(g))[0];
171
- if (!_) throw Error(`PostgresDataStore.upsert: no row returned for table '${e}'`);
272
+ let c = n.conflictColumns.map((e) => s`${s(e)}`), l = Object.keys(t).filter((e) => t[e] !== void 0), u = n.update === void 0 ? l.filter((e) => e !== "id" && !n.conflictColumns.includes(e)) : n.update, d = u.length > 0 ? s.csv(u.map((e) => s`${s(e)} = EXCLUDED.${s(e)}`)) : s`${s(n.conflictColumns[0])} = EXCLUDED.${s(n.conflictColumns[0])}`, f = s`INSERT INTO ${s(e)} ${s.insert(v(t, e, G))} ON CONFLICT (${s.csv(c)}) DO UPDATE SET ${d} RETURNING *`, p = r ? i.provideService(f, k, r) : f, m = (await this.runtime.runPromise(p))[0];
273
+ if (!m) throw Error(`PostgresDataStore.upsert: no row returned for table '${e}'`);
172
274
  {
173
- let n = t.id !== void 0 && t.id === _.id ? "insert" : "update";
275
+ let n = t.id !== void 0 && t.id === m.id ? "insert" : "update";
174
276
  await this.routeEvent({
175
277
  table: e,
176
278
  op: n,
177
279
  old: null,
178
- new: _
179
- }, a, i, o);
280
+ new: m
281
+ }, a, r, o);
180
282
  }
181
- return _;
283
+ return m;
182
284
  }
183
- async executeInsertIgnore(e, t, n, i, a, o) {
184
- t = F(e, t);
185
- let s = this.sql, c = n.conflictColumns.map((e) => s`${s(e)}`), l = s`INSERT INTO ${s(e)} ${s.insert(E(t, e, J))} ON CONFLICT (${s.csv(c)}) DO NOTHING RETURNING *`, u = i ? r.provideService(l, h, i) : l, d = (await this.runtime.runPromise(u))[0];
285
+ async executeInsertIgnore(e, t, n, r, a, o) {
286
+ t = E(e, t);
287
+ let s = this.sql, c = n.conflictColumns.map((e) => s`${s(e)}`), l = s`INSERT INTO ${s(e)} ${s.insert(v(t, e, G))} ON CONFLICT (${s.csv(c)}) DO NOTHING RETURNING *`, u = r ? i.provideService(l, k, r) : l, d = (await this.runtime.runPromise(u))[0];
186
288
  if (d) return await this.routeEvent({
187
289
  table: e,
188
290
  op: "insert",
189
291
  old: null,
190
292
  new: d
191
- }, a, i, o), d;
192
- let f = n.conflictColumns.map((e) => s`${s(e)} = ${t[e]}`), p = s`SELECT * FROM ${s(e)} WHERE ${s.and(f)} LIMIT 1`, m = i ? r.provideService(p, h, i) : p, g = await this.runtime.runPromise(m);
193
- if (!g[0]) throw Error(`PostgresDataStore.insertIgnore: the insert was skipped as a conflict, but no existing row matches conflictColumns [${n.conflictColumns.join(", ")}] on '${e}'. A DIFFERENT unique constraint fired — a second unique index, or the primary key when you named something else. insertIgnore models ONE conflict target: name the columns of the constraint that actually collides, or handle the unique violation yourself.`);
194
- return g[0];
195
- }
196
- async executeInsertMany(e, t, n, i, a) {
197
- if (t = I(e, t), t.length === 0) return [];
198
- let o = this.sql, s = o`INSERT INTO ${o(e)} ${o.insert(t.map((t) => E(t, e, J)))} RETURNING *`, c = n ? r.provideService(s, h, n) : s, l = await this.runtime.runPromise(c);
293
+ }, a, r, o), d;
294
+ let f = n.conflictColumns.map((e) => s`${s(e)} = ${t[e]}`), p = s`SELECT * FROM ${s(e)} WHERE ${s.and(f)} LIMIT 1`, m = r ? i.provideService(p, k, r) : p, h = await this.runtime.runPromise(m);
295
+ if (!h[0]) throw Error(`PostgresDataStore.insertIgnore: the insert was skipped as a conflict, but no existing row matches conflictColumns [${n.conflictColumns.join(", ")}] on '${e}'. A DIFFERENT unique constraint fired — a second unique index, or the primary key when you named something else. insertIgnore models ONE conflict target: name the columns of the constraint that actually collides, or handle the unique violation yourself.`);
296
+ return h[0];
297
+ }
298
+ async executeInsertMany(e, t, n, r, a) {
299
+ if (t = me(e, t), t.length === 0) return [];
300
+ let o = this.sql, s = re(t.map((t) => v(t, e, G)), ne("postgres")), c = (t) => o`INSERT INTO ${o(e)} ${o.insert(t)} RETURNING *`, l;
301
+ if (s.length === 1) {
302
+ let e = c(s[0]), t = n ? i.provideService(e, k, n) : e;
303
+ l = await this.runtime.runPromise(t);
304
+ } else if (n) {
305
+ let e = [];
306
+ for (let t of s) e.push(...await this.runtime.runPromise(i.provideService(c(t), k, n)));
307
+ l = e;
308
+ } else l = await this.runtime.runPromise(o.withTransaction(i.map(i.forEach(s, c, { concurrency: 1 }), (e) => e.flat())));
199
309
  for (let t of l) await this.routeEvent({
200
310
  table: e,
201
311
  op: "insert",
202
312
  old: null,
203
313
  new: t
204
- }, i, n, a);
314
+ }, r, n, a);
205
315
  return l;
206
316
  }
207
- async executePatchJson(e, t, n, i, a, o, s) {
208
- let c = this.sql, l = n.split("."), u = l[0], d = l.slice(1), f = JSON.stringify(i ?? null), p = d.length === 0 ? c`${c(u)} = COALESCE(${c(u)}, '{}'::jsonb) || ${f}::jsonb` : c`${c(u)} = jsonb_set(COALESCE(${c(u)}, '{}'::jsonb), ${`{${d.join(",")}}`}, ${f}::jsonb, true)`, m = c`UPDATE ${c(e)} SET ${p} WHERE ${c("id")} = ${t} RETURNING *`, g = a ? r.provideService(m, h, a) : m, _ = (await this.runtime.runPromise(g))[0];
209
- return _ ? (await this.routeEvent({
317
+ async executePatchJson(e, t, n, r, a, o, s) {
318
+ let c = this.sql, l = n.split("."), u = l[0], d = l.slice(1), f = JSON.stringify(r ?? null), p = d.length === 0 ? c`${c(u)} = COALESCE(${c(u)}, '{}'::jsonb) || ${f}::jsonb` : c`${c(u)} = jsonb_set(COALESCE(${c(u)}, '{}'::jsonb), ${`{${d.join(",")}}`}, ${f}::jsonb, true)`, m = c`UPDATE ${c(e)} SET ${p} WHERE ${c("id")} = ${t} RETURNING *`, h = a ? i.provideService(m, k, a) : m, g = (await this.runtime.runPromise(h))[0];
319
+ return g ? (await this.routeEvent({
210
320
  table: e,
211
321
  op: "update",
212
322
  old: null,
213
- new: _
214
- }, o, a, s), _) : null;
323
+ new: g
324
+ }, o, a, s), g) : null;
215
325
  }
216
- async executeDelete(e, t, n, i, a) {
217
- let o = this.sql, s = o`DELETE FROM ${o(e)} WHERE ${o("id")} = ${t} RETURNING *`, c = n ? r.provideService(s, h, n) : s, l = (await this.runtime.runPromise(c))[0];
326
+ async executeDelete(e, t, n, r, a) {
327
+ let o = this.sql, s = o`DELETE FROM ${o(e)} WHERE ${o("id")} = ${t} RETURNING *`, c = n ? i.provideService(s, k, n) : s, l = (await this.runtime.runPromise(c))[0];
218
328
  return l ? (await this.routeEvent({
219
329
  table: e,
220
330
  op: "delete",
221
331
  old: l,
222
332
  new: null
223
- }, i, n, a), !0) : !1;
333
+ }, r, n, a), !0) : !1;
224
334
  }
225
335
  async appendInTxn(e, t, n) {
226
- let i = this.sql, a = i`INSERT INTO ${i(e)} ${i.insert(E(t, e, J))}`;
227
- await this.runtime.runPromise(n ? r.provideService(a, h, n) : a);
336
+ let r = this.sql, a = r`INSERT INTO ${r(e)} ${r.insert(v(t, e, G))}`;
337
+ await this.runtime.runPromise(n ? i.provideService(a, k, n) : a);
228
338
  }
229
- async maxInTxn(e, t, n, i) {
230
- let a = this.sql, o = Object.entries(n).map(([e, t]) => a`${a(e)} = ${t}`), s = a`SELECT MAX(${a(t)}) AS ${a("m")} FROM ${a(e)} WHERE ${a.and(o)}`, c = (await this.runtime.runPromise(i ? r.provideService(s, h, i) : s))[0]?.m;
339
+ async maxInTxn(e, t, n, r) {
340
+ let a = this.sql, o = Object.entries(n).map(([e, t]) => a`${a(e)} = ${t}`), s = a`SELECT MAX(${a(t)}) AS ${a("m")} FROM ${a(e)} WHERE ${a.and(o)}`, c = (await this.runtime.runPromise(r ? i.provideService(s, k, r) : s))[0]?.m;
231
341
  return c == null ? null : Number(c);
232
342
  }
233
343
  async routeEvent(e, t, n = null, r) {
234
344
  if (e = {
235
- ...v(r),
345
+ ...g(r),
236
346
  ...e
237
- }, j(e.table) && await te({
347
+ }, fe(e.table) && await pe({
238
348
  append: (e, t) => this.appendInTxn(e, t, n),
239
349
  maxOf: (e, t, r) => this.maxInTxn(e, t, r, n)
240
350
  }, {
@@ -244,10 +354,10 @@ var R = (e) => e ? { rejectUnauthorized: !1 } : !1, z = /^[A-Za-z_][A-Za-z0-9_]*
244
354
  prev: e.old,
245
355
  traceId: e.traceId,
246
356
  subjectId: e.subjectId
247
- }), k(e.table)) {
357
+ }), y(e.table)) {
248
358
  if (this.changeStrategy === "cdc") {
249
359
  let t = (e.op === "delete" ? e.old : e.new)?.id;
250
- t != null && M(y(e.table, e.op, t), {
360
+ t != null && x(ee(e.table, e.op, t), {
251
361
  ...e.traceId === void 0 ? {} : { traceId: e.traceId },
252
362
  ...e.subjectId === void 0 ? {} : { subjectId: e.subjectId }
253
363
  });
@@ -260,79 +370,94 @@ var R = (e) => e ? { rejectUnauthorized: !1 } : !1, z = /^[A-Za-z_][A-Za-z0-9_]*
260
370
  return this.runWithEager(e, null);
261
371
  }
262
372
  raw(e, t) {
263
- let n = C(e, this.sql);
264
- return this.runtime.runPromise(n);
265
- }
266
- async runWithEager(e, t) {
267
- if (!O(e)) return this.executeQuery(e, t);
268
- let n = x(e, this.sql, "postgres");
269
- if (n !== null) try {
270
- let e = t ? r.provideService(n.fragment, h, t) : n.fragment, i = await this.runtime.runPromise(e);
271
- return n.decode(i);
272
- } catch (e) {
273
- if (e instanceof g) throw e;
274
- Y.warn("postgres JSON-agg eager-load failed; falling back to walker", { err: e });
373
+ let n = ae(e, this.sql);
374
+ return b("postgres", "raw", () => this.runtime.runPromise(n));
375
+ }
376
+ async runWithEager(e, t, n = null) {
377
+ if (!le(e)) return this.executeQuery(e, t, n);
378
+ let r = n === null ? ie(e, this.sql, "postgres") : null;
379
+ if (r !== null) try {
380
+ let e = t ? i.provideService(r.fragment, k, t) : r.fragment, n = await b("postgres", "select", () => this.runtime.runPromise(e));
381
+ return r.decode(n);
382
+ } catch (t) {
383
+ if (t instanceof m) throw t;
384
+ this.reportEagerFallback({
385
+ dialect: "postgres",
386
+ table: e.table,
387
+ reason: "execute-failed",
388
+ error: t
389
+ });
275
390
  }
276
- return _(await this.executeQuery(e, t), e.eager, e.sourceTable ?? N(e.table), (e) => this.executeQuery(e, t));
391
+ else this.reportEagerFallback({
392
+ dialect: "postgres",
393
+ table: e.table,
394
+ reason: "not-compilable"
395
+ });
396
+ return h(await this.executeQuery(e, t, n), e.eager, e.sourceTable ?? S(e.table), (e) => this.executeQuery(e, t, n));
277
397
  }
278
398
  getInternalRunWithEager() {
279
399
  return (e, t) => this.runWithEager(e, t);
280
400
  }
281
- async localWrite(e, t) {
282
- if (this.changeStrategy !== "cdc") return L(t);
283
- b(e);
284
- try {
285
- return await L(t);
286
- } finally {
287
- D(e);
288
- }
401
+ async queryInNamespace(e, t) {
402
+ return this.runWithEager(t, null, e);
403
+ }
404
+ async localWrite(e, t, n) {
405
+ return b("postgres", e, async () => {
406
+ if (this.changeStrategy !== "cdc") return D(n);
407
+ te(t);
408
+ try {
409
+ return await D(n);
410
+ } finally {
411
+ se(t);
412
+ }
413
+ });
289
414
  }
290
415
  insert(e, t) {
291
- return this.localWrite(e, (n) => this.executeInsert(e, t, null, null, n));
416
+ return this.localWrite("insert", e, (n) => this.executeInsert(e, t, null, null, n));
292
417
  }
293
418
  insertMany(e, t) {
294
- return this.localWrite(e, (n) => this.executeInsertMany(e, t, null, null, n));
419
+ return this.localWrite("insert", e, (n) => this.executeInsertMany(e, t, null, null, n));
295
420
  }
296
421
  patchJson(e, t, n, r) {
297
- return this.localWrite(e, (i) => this.executePatchJson(e, t, n, r, null, null, i));
422
+ return this.localWrite("update", e, (i) => this.executePatchJson(e, t, n, r, null, null, i));
298
423
  }
299
424
  update(e, t, n) {
300
- return this.localWrite(e, (r) => this.executeUpdate(e, t, n, null, null, r));
425
+ return this.localWrite("update", e, (r) => this.executeUpdate(e, t, n, null, null, r));
301
426
  }
302
427
  delete(e, t) {
303
- return this.localWrite(e, (n) => this.executeDelete(e, t, null, null, n));
428
+ return this.localWrite("delete", e, (n) => this.executeDelete(e, t, null, null, n));
304
429
  }
305
430
  async updateMany(e, t, n) {
306
- return this.localWrite(e, (r) => this.executeUpdateMany(e, t, n, null, null, r));
431
+ return this.localWrite("update", e, (r) => this.executeUpdateMany(e, t, n, null, null, r));
307
432
  }
308
433
  async deleteMany(e, t) {
309
- return this.localWrite(e, (n) => this.executeDeleteMany(e, t, null, null, n));
434
+ return this.localWrite("delete", e, (n) => this.executeDeleteMany(e, t, null, null, n));
310
435
  }
311
- async executeUpdateMany(e, t, n, i, a, o) {
312
- let s = this.sql, c = S(n.where, s), l = s`UPDATE ${s(e)} SET ${s.update(E(t, e, J))} WHERE ${c} RETURNING *`, u = i ? r.provideService(l, h, i) : l, d = await this.runtime.runPromise(u);
436
+ async executeUpdateMany(e, t, n, r, a, o) {
437
+ let s = this.sql, c = _(n.where, s), l = s`UPDATE ${s(e)} SET ${s.update(v(t, e, G))} WHERE ${c} RETURNING *`, u = r ? i.provideService(l, k, r) : l, d = await this.runtime.runPromise(u);
313
438
  for (let t of d) await this.routeEvent({
314
439
  table: e,
315
440
  op: "update",
316
441
  old: null,
317
442
  new: t
318
- }, a, i, o);
443
+ }, a, r, o);
319
444
  return d.length;
320
445
  }
321
- async executeDeleteMany(e, t, n, i, a) {
322
- let o = this.sql, s = S(t.where, o), c = o`DELETE FROM ${o(e)} WHERE ${s} RETURNING *`, l = n ? r.provideService(c, h, n) : c, u = await this.runtime.runPromise(l);
446
+ async executeDeleteMany(e, t, n, r, a) {
447
+ let o = this.sql, s = _(t.where, o), c = o`DELETE FROM ${o(e)} WHERE ${s} RETURNING *`, l = n ? i.provideService(c, k, n) : c, u = await this.runtime.runPromise(l);
323
448
  for (let t of u) await this.routeEvent({
324
449
  table: e,
325
450
  op: "delete",
326
451
  old: t,
327
452
  new: null
328
- }, i, n, a);
453
+ }, r, n, a);
329
454
  return u.length;
330
455
  }
331
456
  upsert(e, t, n) {
332
- return this.localWrite(e, (r) => this.executeUpsert(e, t, n, null, null, r));
457
+ return this.localWrite("upsert", e, (r) => this.executeUpsert(e, t, n, null, null, r));
333
458
  }
334
459
  insertIgnore(e, t, n) {
335
- return this.localWrite(e, (r) => this.executeInsertIgnore(e, t, n, null, null, r));
460
+ return this.localWrite("upsert", e, (r) => this.executeInsertIgnore(e, t, n, null, null, r));
336
461
  }
337
462
  emitChange(e) {
338
463
  this.emitter.emit("change", e);
@@ -368,28 +493,13 @@ var R = (e) => e ? { rejectUnauthorized: !1 } : !1, z = /^[A-Za-z_][A-Za-z0-9_]*
368
493
  return this.executeInsertIgnore.bind(this);
369
494
  }
370
495
  async transactional(e) {
371
- this.inflightTxns++, T();
372
- let t = Z(), n = 0, i = r.suspend(() => {
373
- let i = ++n;
374
- return this.sql.withTransaction(r.flatMap(r.serviceOption(h), (n) => {
375
- if (s.isNone(n)) return r.fail(/* @__PURE__ */ Error("PostgresDataStore.transactional: TransactionConnection unexpectedly missing inside withTransaction."));
376
- let a = new Q(this, n.value);
377
- return r.tryPromise({
378
- try: () => t(() => e(a)).then((e) => ({
379
- result: e,
380
- view: a,
381
- attempt: i
382
- })),
383
- catch: (e) => e
384
- });
385
- }));
386
- }), a = l.exponential("10 millis").pipe(l.compose(l.recurs(3)), l.whileInput(K)), o = i.pipe(r.retry(a), r.withSpan("store.transactional", { attributes: {
387
- "db.system": "postgresql",
388
- "db.operation": "transaction"
389
- } }));
496
+ this.inflightTxns++;
390
497
  try {
391
- let e = ne(await this.runtime.runPromiseExit(o));
392
- return e.view.commitEvents(), e.result;
498
+ return await T({
499
+ ...this.txnSpec("PostgresDataStore.transactional", "store.transactional", "transaction"),
500
+ work: e,
501
+ makeView: (e, t) => new J(this, e, t)
502
+ });
393
503
  } finally {
394
504
  this.inflightTxns--;
395
505
  }
@@ -403,14 +513,10 @@ var R = (e) => e ? { rejectUnauthorized: !1 } : !1, z = /^[A-Za-z_][A-Za-z0-9_]*
403
513
  return this.changeStrategy === "cdc" ? "fleet" : "local";
404
514
  }
405
515
  injectExternalChange(e) {
406
- if (!k(e.table)) return;
516
+ if (!y(e.table)) return;
407
517
  let t = (e.op === "delete" ? e.old : e.new)?.id;
408
- P(e.table, e.op, t, (t) => {
409
- this.emitter.emit("change", {
410
- ...t,
411
- ...e,
412
- origin: "injected"
413
- });
518
+ C(e.table, e.op, t, (t) => {
519
+ this.emitter.emit("change", ce(e, t));
414
520
  });
415
521
  }
416
522
  run(e) {
@@ -420,28 +526,55 @@ var R = (e) => e ? { rejectUnauthorized: !1 } : !1, z = /^[A-Za-z_][A-Za-z0-9_]*
420
526
  if (this.inflightTxns > 0) {
421
527
  let t = Date.now() + e;
422
528
  for (; this.inflightTxns > 0 && Date.now() < t;) await new Promise((e) => setTimeout(e, 25));
423
- this.inflightTxns > 0 && Y.warn("close: grace period expired with in-flight transactions — forcing dispose", {
529
+ this.inflightTxns > 0 && K.warn("close: grace period expired with in-flight transactions — forcing dispose", {
424
530
  gracePeriodMs: e,
425
531
  inflight: this.inflightTxns
426
532
  });
427
533
  }
428
- this.cdcFiber &&= (await this.runtime.runPromise(i.interrupt(this.cdcFiber)), null), await this.runtime.dispose();
534
+ this.cdcFiber &&= (await this.runtime.runPromise(a.interrupt(this.cdcFiber)), null), await this.runtime.dispose();
429
535
  }
430
536
  async ping() {
431
537
  await this.runtime.runPromise(this.sql`SELECT 1`);
432
538
  }
539
+ readRowAsCdcJson(e, t, n) {
540
+ let r = this.sql, a = e === void 0 || e === "" ? r`${r(t)}` : r`${r(e)}.${r(t)}`;
541
+ return r`
542
+ SELECT row_to_json(t)::text AS ${r("payload")} FROM ${a} t WHERE t.${r("id")} = ${n} LIMIT 1
543
+ `.pipe(i.map((e) => {
544
+ let t = e[0]?.payload;
545
+ return t == null ? null : JSON.parse(t);
546
+ }));
547
+ }
433
548
  async startCdcConsumer() {
434
- let e = (await this.runtime.runPromise(t.PgClient)).listen(this.cdcChannel), n = (e) => {
549
+ let e = (await this.runtime.runPromise(t.PgClient)).listen(this.cdcChannel), n = (e) => i.suspend(() => {
550
+ let t;
435
551
  try {
436
- let t = JSON.parse(e);
437
- this.injectExternalChange(t);
552
+ t = JSON.parse(e);
438
553
  } catch (e) {
439
- Y.warn("cdc: bad payload", { channel: this.cdcChannel }, e);
554
+ return K.warn("cdc: bad payload", { channel: this.cdcChannel }, e), i.void;
440
555
  }
441
- };
442
- this.cdcFiber = this.runtime.runFork(e.pipe(u.runForEach((e) => r.sync(() => n(e)))));
556
+ if (t.oversized !== !0) {
557
+ let e = {
558
+ table: t.table,
559
+ op: t.op,
560
+ old: t.old,
561
+ new: t.new
562
+ };
563
+ return i.sync(() => {
564
+ this.injectExternalChange(e);
565
+ });
566
+ }
567
+ return y(t.table) ? be({
568
+ notification: t,
569
+ fetchRow: ({ schema: e, table: t, key: n }) => this.readRowAsCdcJson(e, t, n),
570
+ tunables: this.cdcRehydrate
571
+ }).pipe(i.map((e) => {
572
+ this.reportOversized(t, e), this.injectExternalChange(e.event);
573
+ })) : i.void;
574
+ });
575
+ this.cdcFiber = this.runtime.runFork(e.pipe(d.runForEach(n)));
443
576
  }
444
- }, Q = class {
577
+ }, J = class {
445
578
  parent;
446
579
  txn;
447
580
  attr;
@@ -496,14 +629,14 @@ var R = (e) => e ? { rejectUnauthorized: !1 } : !1, z = /^[A-Za-z_][A-Za-z0-9_]*
496
629
  this.events.length = 0;
497
630
  }
498
631
  }
499
- }, ie = class {
632
+ }, Ce = class {
500
633
  parent;
501
634
  namespace;
502
635
  constructor(e, t) {
503
636
  this.parent = e, this.namespace = t;
504
637
  }
505
638
  query(e) {
506
- return this.parent.runInNamespace(this.namespace, (t) => t.query(e));
639
+ return this.parent.queryInNamespace(this.namespace, e);
507
640
  }
508
641
  insert(e, t) {
509
642
  return this.parent.runInNamespace(this.namespace, (n) => n.insert(e, t));
@@ -550,39 +683,109 @@ var R = (e) => e ? { rejectUnauthorized: !1 } : !1, z = /^[A-Za-z_][A-Za-z0-9_]*
550
683
  return r === void 0 ? Promise.reject(/* @__PURE__ */ Error("PostgresNamespaceView.raw: underlying store has no raw()")) : r(e, t);
551
684
  });
552
685
  }
553
- }, $ = (e) => e.__postgresReplicationFriend ?? null, ae = (e, t) => {
686
+ }, Y = (e) => e.__postgresReplicationFriend ?? null, we = (e, t) => {
554
687
  let [n, r] = e.split("/"), [i, a] = t.split("/");
555
688
  if (!n || !r || !i || !a) throw Error(`postgres LSN compare: invalid format (${e} vs ${t})`);
556
689
  let o = parseInt(n, 16), s = parseInt(r, 16), c = parseInt(i, 16);
557
690
  return o === c ? s - parseInt(a, 16) : o - c;
558
- }, oe = () => ({
691
+ }, Te = () => ({
559
692
  async capturePrimaryPosition(e) {
560
- let t = $(e);
693
+ let t = Y(e);
561
694
  if (t === null) throw Error("postgresReplicationAdapter: primary is not a PostgresDataStore (missing __postgresReplicationFriend). Pass the postgres store directly.");
562
- return t.runEffect(r.gen(function* () {
563
- let e = (yield* (yield* m)`SELECT pg_current_wal_lsn()::text AS lsn`)[0]?.lsn;
564
- return typeof e == "string" ? e : yield* r.die("postgres did not return a WAL LSN");
695
+ return t.runEffect(i.gen(function* () {
696
+ let e = (yield* (yield* O)`SELECT pg_current_wal_lsn()::text AS lsn`)[0]?.lsn;
697
+ return typeof e == "string" ? e : yield* i.die("postgres did not return a WAL LSN");
565
698
  }));
566
699
  },
567
700
  async probeReplicaPosition(e) {
568
- let t = $(e);
701
+ let t = Y(e);
569
702
  if (t === null) throw Error("postgresReplicationAdapter: replica is not a PostgresDataStore.");
570
- return t.runEffect(r.gen(function* () {
571
- let e = (yield* (yield* m)`
703
+ return t.runEffect(i.gen(function* () {
704
+ let e = (yield* (yield* O)`
572
705
  SELECT COALESCE(pg_last_wal_replay_lsn()::text, pg_current_wal_lsn()::text) AS lsn
573
706
  `)[0]?.lsn;
574
- return typeof e == "string" ? e : yield* r.die("postgres did not return a replay LSN");
707
+ return typeof e == "string" ? e : yield* i.die("postgres did not return a replay LSN");
575
708
  }));
576
709
  },
577
710
  compare(e, t) {
578
- return ae(t, e) >= 0 ? "caught-up" : "behind";
579
- }
580
- }), se = {
711
+ return we(t, e) >= 0 ? "caught-up" : "behind";
712
+ }
713
+ }), X = (e) => `"${e.replace(/"/g, "\"\"")}"`, Ee = (e) => e.replace(/\\/g, "\\\\").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\v/g, "\\v").replace(/\f/g, "\\f").replace(/[\b]/g, "\\b"), De = (e) => {
714
+ let t = "";
715
+ for (let n of e) t += n.toString(16).padStart(2, "0");
716
+ return t;
717
+ }, Z = (e) => `{${e.map((e) => e == null ? "NULL" : Array.isArray(e) ? Z(e) : typeof e == "number" || typeof e == "bigint" ? String(e) : typeof e == "boolean" ? e ? "t" : "f" : `"${(e instanceof Date ? e.toISOString() : String(e)).replace(/\\/g, "\\\\").replace(/"/g, "\\\"")}"`).join(",")}}`, Q = (e, t) => e == null ? null : typeof e == "string" ? e : typeof e == "number" || typeof e == "bigint" ? String(e) : typeof e == "boolean" ? e ? "t" : "f" : e instanceof Date ? e.toISOString() : e instanceof Uint8Array ? `\\x${De(e)}` : Array.isArray(e) && t === "array" ? Z(e) : JSON.stringify(e), $ = (e, t, n = {}) => t.map((t) => {
718
+ let r = Q(e[t], n[t]);
719
+ return r === null ? "\\N" : Ee(r);
720
+ }).join(" "), Oe = class {
721
+ text;
722
+ chunks;
723
+ done;
724
+ settled = !1;
725
+ rowCount = 0;
726
+ constructor(e, t, n) {
727
+ this.text = e, this.chunks = t, this.done = n;
728
+ }
729
+ settle(e) {
730
+ this.settled || (this.settled = !0, this.done(e, this.rowCount));
731
+ }
732
+ submit(e) {
733
+ e.query(this.text);
734
+ }
735
+ handleCopyInResponse(e) {
736
+ for (let t of this.chunks) e.sendCopyFromChunk(t);
737
+ e.endCopyFrom();
738
+ }
739
+ handleCommandComplete(e) {
740
+ let t = /COPY (\d+)/.exec(e?.text ?? "");
741
+ t && (this.rowCount = Number(t[1]));
742
+ }
743
+ handleRowDescription() {}
744
+ handleDataRow() {}
745
+ handleError(e) {
746
+ this.settle(e);
747
+ }
748
+ handleReadyForQuery() {
749
+ this.settle(void 0);
750
+ }
751
+ }, ke = (e) => ({
752
+ ...e.url ? { connectionString: e.url } : {
753
+ host: e.host ?? "localhost",
754
+ port: e.port ?? 5432,
755
+ user: e.username ?? "postgres",
756
+ password: e.password ?? "",
757
+ database: e.database ?? "postgres"
758
+ },
759
+ ...e.ssl === !0 ? { ssl: { rejectUnauthorized: !1 } } : {}
760
+ }), Ae = 64 * 1024, je = (e) => {
761
+ let t, n, r = () => t ? Promise.resolve(t) : (n ??= (async () => {
762
+ let n = new f.Client(ke(e));
763
+ return await n.connect(), t = n, n;
764
+ })(), n);
765
+ return {
766
+ dialect: "postgres",
767
+ copyInto: async ({ table: e, columns: t, columnTypes: n, rows: i }) => {
768
+ if (i.length === 0) return 0;
769
+ let a = await r(), o = `COPY ${X(e)} (${t.map(X).join(", ")}) FROM STDIN`, s = [], c = "";
770
+ for (let e of i) c += $(e, t, n ?? {}), c += "\n", c.length >= Ae && (s.push(Buffer.from(c, "utf8")), c = "");
771
+ return c.length > 0 && s.push(Buffer.from(c, "utf8")), await new Promise((e, t) => {
772
+ let n = new Oe(o, s, (n, r) => {
773
+ n ? t(n) : e(r);
774
+ });
775
+ a.query(n);
776
+ });
777
+ },
778
+ close: async () => {
779
+ let e = t;
780
+ t = void 0, n = void 0, e && await e.end().catch(() => void 0);
781
+ }
782
+ };
783
+ }, Me = {
581
784
  id: "postgres",
582
- makeSqlLayer: (e) => U(e),
583
- makeStore: (e) => X(e),
785
+ makeSqlLayer: (e) => L(e),
786
+ makeStore: (e) => q(e),
584
787
  compileContains: (e, t, n) => n`${e} ILIKE ${`%${t.replace(/[\\%_]/g, (e) => `\\${e}`)}%`} ESCAPE '\\'`,
585
- retryFilter: q
788
+ retryFilter: B
586
789
  };
587
790
  //#endregion
588
- export { e as PgClient, H as connectionFromConfig, X as makePostgresDataStore, B as makePostgresSqlLayer, U as makePostgresSqlLayerFromConfig, se as postgresDialect, oe as postgresReplicationAdapter, q as postgresRetryFilter };
791
+ export { e as PgClient, I as connectionFromConfig, $ as encodeCopyRow, Q as encodeCopyValue, je as makePgCopySession, q as makePostgresDataStore, P as makePostgresSqlLayer, L as makePostgresSqlLayerFromConfig, Me as postgresDialect, Te as postgresReplicationAdapter, B as postgresRetryFilter };